zoukankan      html  css  js  c++  java
  • 关于Boolean类型做为同步锁异常问题

    public class Test2 {
    
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> volatile Boolean aBoolean = <span class="hljs-keyword">true</span>;
    <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">A</span> <span class="hljs-inheritance"><span class="hljs-keyword">implements</span></span> <span class="hljs-title">Runnable</span>{</span>
        @Override
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> run() {
            synchronized (aBoolean){
                <span class="hljs-keyword">while</span> (aBoolean){
                    <span class="hljs-keyword">try</span> {
                        System.out.println(<span class="hljs-string">"进入A, 等待中"</span>);
                        aBoolean.wait();
                    } <span class="hljs-keyword">catch</span> (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(<span class="hljs-string">"A over"</span>);
            }
        }
    }
    
    <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">B</span> <span class="hljs-inheritance"><span class="hljs-keyword">implements</span></span> <span class="hljs-title">Runnable</span>{</span>
    
        @Override
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> run() {
    
            <span class="hljs-keyword">try</span> {
                TimeUnit.SECONDS.sleep(<span class="hljs-number">3</span>);
            } <span class="hljs-keyword">catch</span> (InterruptedException e) {
                e.printStackTrace();
            }
    
            synchronized (aBoolean){
                System.out.println(<span class="hljs-string">"通知A可以运行了"</span>);
                aBoolean = <span class="hljs-keyword">false</span>;
                aBoolean.notifyAll(); 
                <span class="hljs-comment">//Boolean.TRUE.notifyAll();</span>
            }
        }
    }
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> main(String[] args) {
        <span class="hljs-keyword">new</span> Thread(<span class="hljs-keyword">new</span> A()).start();
        <span class="hljs-keyword">new</span> Thread(<span class="hljs-keyword">new</span> B()).start();
    }
    

    }

    运行结果:

    进入A, 等待中
    通知A可以运行了
    Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
        at java.lang.Object.notifyAll(Native Method)
        at Test2$B.run(Test2.java:39)
        at java.lang.Thread.run(Thread.java:748)
    由于我们会给aBoolean重新赋值, 导致对象监视器改变, 因为falsetrue这两个常量对应着两个不同的对象。当aBoolean产生变化时,很可能导致不同的线程同步了不同的对象
    解决方法: 
    将这一行 aBoolean.notifyAll();  改为: Boolean.TRUE.notifyAll();
    或者是用显示锁ReentrantLock的方式
  • 相关阅读:
    Spring Cloud概述
    Servlet调用流程和Spring MVC调用流程
    待看文章链接
    MyBatis之 resultMap 元素子元素详解
    MyBatis核心配置文件模板代码
    ios上架
    iOS打包部署
    Android XML绘图(4)——Bitmap
    Android XML绘图(2)——Layer
    Android XML绘图(3)——Selector
  • 原文地址:https://www.cnblogs.com/jpfss/p/9620127.html
Copyright © 2011-2022 走看看