Integer类型变量 使用wait notify 报错

2020-04-22  本文已影响0人  躺着真的舒服

最近看面试题刷到了synchronized 锁问题,提到了synchronized 中wait notify的使用,自己写了段代码测试了一下。

public class SynchronizeTest {
    // 商品数量
    private Integer x=0;

    public static void main(String[] args) {
        SynchronizeTest ze=new SynchronizeTest();
        Thread produce=new Thread(){
            @Override
            public void run() {
                ze.produce();
            }
        };
        Thread consumer=new Thread(){
            @Override
            public void run() {
                ze.consumer();

            }
        };
        consumer.start();
        produce.start();
    }

    // 生产者
    public void  produce(){
        synchronized (x){
            System.out.println("produce已获取锁");
            if(x<=0){
                x++;
                x.notify();
                System.out.println("produce释放锁");
            }
        }
    }
    // 消费者
    public void consumer(){
        try {
            synchronized (x){
                System.out.println("consumer获取到锁");
            while(x<=0){
                x.wait();
                System.out.println("consumer锁改为等待状态");
                x--;
            }
            }
            System.out.println("consumer释放锁");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果如下

consumer获取到锁
produce已获取锁
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at com.锁.SynchronizeTest.produce(SynchronizeTest.java:34)
    at com.锁.SynchronizeTest$1.run(SynchronizeTest.java:14)

这个错误提示显示produce方法在notify时获取不到x的monitor对象,但是我明明已经用synchronized获取到x的监视器锁了呀,后来经过多次试验才发现了原因,大家都知道Integer类型是final类型的,运算符++操作是把x指向了一个新的对象1,而我们获取到的监视器锁是对象0的,so...
同理像String、Boolean应该也是这种情况.

上一篇下一篇

猜你喜欢

热点阅读