在学习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却完全没有。可以看出好像只会在操作同步监视器的那一行上锁一样。我以为只有在一个线程执行完同步块后另外一个线程才有机会进入。这是我的一个误区。同步块中最好还是就写相关的操作吧。经过验证Lock锁不存在上述情况
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/195258.html