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();
        }
        }