在学习synchronized时发现了一个有趣的现象:
public class MyThread implements Runnable {
private int number=10;
private boolean flag = true;
@Override
public void run() {
while (flag) {
//同步块,()填变化的量必须是引用类型,锁定的就是传入参数
synchronized (Integer.valueOf(number)){
number--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (number < 1) {
flag=false;
}
else {
System.out.println(Thread.currentThread().getName() + "--" + number);
}
}
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
new Thread(myThread,"李").start();
new Thread(myThread,"马").start();
new Thread(myThread,"王").start();
}
}
/*
李--7
马--7
王--7
王--4
李--4
马--4
李--1
马--1
王--1
我以为只有在一个线程执行完同步块后另外一个线程才有机会进入,但上述情况却像是一旦对同步监视器的相关操作(加减乘除)结束后其他线程就已经可以进入同步块了,以至于造成上述情况:李在进入后执行减操作,之后休眠,同时马进入同样执行减操作后休眠,王重复上述操作,在三者都先后执行完休眠操作,但是此时的number却已经被减了三次了使用呈现上述的删除结果
再做一次实验:
public class MyThread implements Runnable {
private static Integer number=10;
private static Integer number1=10;
private boolean flag = true;
@Override
public void run() {
while (flag) {
synchronized (number){
if (number < 1) {
flag=false;
}
else {
System.out.println(Thread.currentThread().getName() + "--number--" +number);
number--;
System.out.println(Thread.currentThread().getName() + "--number1--" +number1--);
}
}
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
new Thread(myThread,"李").start();
new Thread(myThread,"马").start();
new Thread(myThread,"王").start();
}
}
/*
李--number--10
李--number1--10
李--number--9
李--number1--9
王--number--9
李--number--8
王--number1--8
李--number1--7
马--number--6
王--number--6
马--number1--6
王--number1--5
马--number--4
李--number--4
马--number1--4
李--number1--3
马--number--2
王--number--2
马--number1--2
王--number1--1
可以看到number出现了多次重复,number1却完全没有。可以看出好像只会在操作同步监视器的那一行上锁一样。我以为只有在一个线程执行完同步块后另外一个线程才有机会进入。这是我的一个误区。同步块中最好还是就写相关的操作吧
标签:Thread,synchronized,--,number,myThread,现象,number1,new,有趣 From: https://www.cnblogs.com/rainaftersummert/p/17438604.html