Java并发编程学习

Java并发编程学习

ID:39550232

大小:66.00 KB

页数:11页

时间:2019-07-06

Java并发编程学习_第1页
Java并发编程学习_第2页
Java并发编程学习_第3页
Java并发编程学习_第4页
Java并发编程学习_第5页
资源描述:

《Java并发编程学习》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、Java并发编程学习一对象的共享线程之间对象的共享不仅仅需要有原子性和临界区,还有一个重要方面:内存可见性1可见性读操作的线程并非可以一直获取到写线程写入的最新值,例如:代码示例privatestaticbooleanready;privatestaticintnumber;privatestaticclassReaderThreadextendsThread{publicvoidrun(){while(!ready)Thread.yield();System.out.println(number);}}publicstaticvoidmain(String[]

2、args){newReaderThread().start();number=42;ready=true;}以上实例代码可能存在如下问题:一直循环下去,因为读线程可能看不到写线程写入了ready。在读线程中输出0,因为主线程可能对number和ready的赋值顺序进行了改变。这是由于线程之间没有正确使用同步使得数据在多个线程中共享出现错误导致的。常见的问题包括:读取到的数据已经失效没有对64位数据同步读写失效的数据以上述例子来说,当读线程读取ready变量的时候,很可能该变量已经失效。失效的数据通常包括两类数据:值数据引用数据值数据的失效例如一个计数器应用,如果

3、不对count变量进行同步处理的话可能会导致计数不准的问题。如果对象的引用失效可能会导致一些莫名其妙的问题,比如意料之外的异常,被破坏的数据结果,不精确的计算及无限循环等。非原子的64位操作根据Java内存模型的要求,变量的读写操作必须是原子操作。对于非volatile类型的long和double变量,JVM允许将64位读写操作分解为两个32为的操作,这样在多线程环境中共享可变的long和double变量也是不安全的。一般的解决方式可以通过加锁或者声明变量为volatile变量。内置锁可以用于确保某个线程以一种可预测的方式看到另一个线程执行的结果。加锁的含义不仅

4、仅局限于互斥行为,还包括了内存可见性。Java同时提供了一种较弱的同步机制,即volatile变量。volatile变量不同于加锁机制,加锁机制可以保证原子性和可见性,但是volatile只能保证可见性。volatile变量会确保将变量的更新结果通知到其他线程,被声明volatile变量会有两个效果:不会对该变量重排序;不会缓存在寄存器或者其他处理器不可见的地方。使用volatile变量可以不执行加锁操作,也不会阻塞线程,开销要比同步要低。但是只能确保可见性,不能确保原子性,更不能保证在volatile变量递增操作的原子性,在使用的时候要注意。当满足以下所有条件

5、时才应该使用volatile变量:对变量写入不依赖当前值,或者确保只有单个线程更新变量的值;该变量不被要求与其他变量同步变化;在访问该变量时不需要加锁,因为加上锁就没必要使用volatile了。2发布与逸出发布一个对象是指使一个对象能在当前作用域之外的代码中使用。一般是将成员变量或静态变量公开。对于一个类的外部方法是不完全由该类规定的方法,包括该类以外定义的方法及由该类定义但可以被改写的方法。当把一个对象传递给一个外部方法,就相当于发布了这个对象。逸出一个对象是指某个不应该发布的对象被发布安全构造对象错误的构造对象方式publicThisEscape(Event

6、Sourcesource){source.registerListener(newEventListener(){publicvoidonEvent(Evente){doSomething(e);}});}在EventListener中保留了this的引用,因此会将this引用逸出。一定不要在构造过程中使this引用逸出。在构造对象的过程中常见的问题:构造函数中将自己的引用传递给一个线程并将该线程启动;构造函数中调用一个可被改写的方法如果构造函数中需要注册事件监听器或者启动线程,一个办法是将构造函数私有化,用工厂模式初始化。例如:privatefinalEven

7、tListenerlistener;privateSafeListener(){listener=newEventListener(){publicvoidonEvent(Evente){doSomething(e);}};}publicstaticSafeListenernewInstance(EventSourcesource){SafeListenersafe=newSafeListener();source.registerListener(safe.listener);returnsafe;}3线程间的变量对于多线程相关的变量,使用的时候有两种策略,一

8、种不希望被共享,使用线程

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。