Java 使用静态包装器类对象时同步不起作用。为什么?
我试着用两个不同的线程打印偶数和奇数 代码如下:Java 使用静态包装器类对象时同步不起作用。为什么?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我试着用两个不同的线程打印偶数和奇数 代码如下: public class OddEvenThread extends Thread{ static Integer counter = 2; static Object lock = new Object(); int max = 20; public void printEven() throws InterruptedException{ synchronized(counter){
public class OddEvenThread extends Thread{
static Integer counter = 2;
static Object lock = new Object();
int max = 20;
public void printEven() throws InterruptedException{
synchronized(counter){
while(counter < (max-1)){
while(counter % 2 != 0){
System.out.println("Even thread Waiting");
counter.wait();
System.out.println("notified");
}
System.out.println("Even thread printing: "+ counter);
counter++;
System.out.println("Notifying odd thread"+counter);
counter.notify();
}
}
}
public void printOdd() throws InterruptedException{
synchronized(counter){
while(counter < (max-1)){
while(counter % 2 == 0){
System.out.println("Odd thread Waiting");
counter.wait();
System.out.println("notified");
}
System.out.println("Odd thread printing: "+ counter);
counter++;
System.out.println("Notifying even thread"+ counter);
counter.notify();
}
}
}
public static void main(String[] args) throws InterruptedException {
OddEvenThread t1 = new OddEvenThread(){
public void run(){
try {
printEven();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
OddEvenThread t2 = new OddEvenThread(){
public void run(){
try {
printOdd();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Complete");
}
}
如果使用不同的静态锁(参考第3行),则代码工作正常。在这种情况下,同步块如下所示:
synchronized(lock){
while(counter < (max-1)){
while(counter % 2 != 0){
System.out.println("Even thread Waiting");
lock.wait();
System.out.println("notified");
}
System.out.println("Even thread printing: "+ counter);
counter++;
System.out.println("Notifying odd thread"+counter);
lock.notify();
}
}
已同步(锁定){
同时(计数器<(最大值1)){
同时(计数器%2!=0){
System.out.println(“偶数线程等待”);
lock.wait();
系统输出打印项次(“已通知”);
}
System.out.println(“偶数线程打印:+计数器”);
计数器++;
System.out.println(“通知奇数线程”+计数器);
lock.notify();
}
}
我在这段代码中遗漏了什么?每次将对象用作锁时,请确保它声明为final,因为锁永远不会更改。一旦你这么做了,你就会知道问题出在哪里了。一般来说,使用整数作为锁是一个糟糕的想法。特别是像2这样的一个池。只是说显式:
synchronized
操作对象,而不是变量。当可以指向不同的对象时,对synchronized
使用相同的变量没有帮助。
synchronized(lock){
while(counter < (max-1)){
while(counter % 2 != 0){
System.out.println("Even thread Waiting");
lock.wait();
System.out.println("notified");
}
System.out.println("Even thread printing: "+ counter);
counter++;
System.out.println("Notifying odd thread"+counter);
lock.notify();
}
}