今天在写一个小demo的时候,要求在多线程环境下,能够顺序输出100-0的数据,在使用synchronize关键字加锁时,锁的位置不对,造成输出结果与预期不一致的问题。
原因在于线程2已经抢占到线程资源,此时判断条件还符合while循环条件,线程阻塞等待线程1的代码执行完毕。但是此时条件判断已经进来了,所以在最后多进行了一次输出操作。
源代码:
public class PrintNumber {
public static int count = 100;
public static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
public void run() {
while (count > 0) {
synchronized (lock) {
//if(count>0){
count--;
System.out.println(Thread.currentThread().getName() + "线程1操作了共享变量,当前共享变量值为:" + count);
// }
}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while (count > 0) {
synchronized (lock) {
//if(count>0){
count--;
System.out.println(Thread.currentThread().getName() + "线程2操作了共享变量,当前共享变量值为:" + count);
//}
}
}
}
}).start();
Thread.sleep(1000);
System.out.println("结束");
}
}
输出结果:
修改后:
public class PrintNumber {
public static int count = 100;
public static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
public void run() {
//修改这里的代码顺序
synchronized (lock) {
while (count > 0) {
//if(count>0){
count--;
System.out.println(Thread.currentThread().getName() + "线程1操作了共享变量,当前共享变量值为:" + count);
// }
}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
//修改这里的代码顺序
synchronized (lock) {
while (count > 0) {
//if(count>0){
count--;
System.out.println(Thread.currentThread().getName() + "线程2操作了共享变量,当前共享变量值为:" + count);
//}
}
}
}
}).start();
Thread.sleep(1000);
System.out.println("结束");
}
}
输出结果:
也可以用死循环直接判断是否满足条件,这样就不会有错啦,敲代码的时候要仔细点啊