多线程 2(线程安全与共享资源)
来源:互联网 发布:ubuntu opencv 编辑:程序博客网 时间:2024/05/18 03:58
允许被多个线程同时执行的代码称作线程安全的代码。线程安全的代码不包含竞态条件。当多个线程同时更新共享资源时会引发竞态条件。因此,了解 Java 线程执行时共享了什么资源很重要。
局部变量
局部变量存储在线程自己的栈中。也就是说,局部变量永远也不会被多个线程共享。所以,基础类型的局部变量是线程安全的。下面是基础类型的局部变量的一个例子:
public void someMethod(){ long threadSafeInt = 0; threadSafeInt++;}
局部的对象引用
对象的局部引用和基础类型的局部变量不太一样。尽管引用本身没有被共享,但引用所指的对象并没有存储在线程的栈内。所有的对象都存在共享堆中。如果在某个方法中创建的对象不会逃逸出(译者注:即该对象不会被其它方法获得,也不会被非局部变量引用到)该方法,那么它就是线程安全的。实际上,哪怕将这个对象作为参数传给其它方法,只要别的线程获取不到这个对象,那它仍是线程安全的。下面是一个线程安全的局部引用样例:
public void someMethod(){ LocalObject localObject = new LocalObject(); localObject.callMethod(); method2(localObject);}public void method2(LocalObject localObject){ localObject.setValue("value");}
样例中 LocalObject 对象没有被方法返回,也没有被传递给 someMethod()方法外的对象。每个执行 someMethod()的线程都会创建自己的 LocalObject 对象,并赋值给 localObject 引用。因此,这里的 LocalObject 是线程安全的。事实上,整个 someMethod()都是线程安全的。即使将 LocalObject 作为参数传给同一个类的其它方法或其它类的方法时,它仍然是线程安全的。当然,如果 LocalObject 通过某些方法被传给了别的线程,那它就不再是线程安全的了。
对象成员
对象成员存储在堆上。如果两个线程同时更新同一个对象的同一个成员,那这个代码就不是线程安全的。下面是一个样例:
public class NotThreadSafe{ StringBuilder builder = new StringBuilder(); public add(String text){ this.builder.append(text); } }
如果两个线程同时调用同一个 NotThreadSafe 实例上的 add()方法,就会有竞态条件问题。例如:
NotThreadSafe sharedInstance = new NotThreadSafe();new Thread(new MyRunnable(sharedInstance)).start();new Thread(new MyRunnable(sharedInstance)).start();public class MyRunnable implements Runnable{ NotThreadSafe instance = null; public MyRunnable(NotThreadSafe instance){ this.instance = instance; } public void run(){ this.instance.add("some text"); }}
注意两个 MyRunnable 共享了同一个 NotThreadSafe 对象。因此,当它们调用 add()方法时会造成竞态条件。
当然,如果这两个线程在不同的 NotThreadSafe 实例上调用 call()方法,就不会导致竞态条件。下面是稍微修改后的例子:
new Thread(new MyRunnable(new NotThreadSafe())).start();new Thread(new MyRunnable(new NotThreadSafe())).start();
现在两个线程都有自己单独的 NotThreadSafe 对象,调用 add()方法时就会互不干扰,再也不会有竞态条件问题了。所以非线程安全的对象仍可以通过某种方式来消除竞态条件。
- 多线程 2(线程安全与共享资源)
- 线程安全与共享资源
- 线程安全与共享资源
- 线程安全与共享资源
- 线程安全与共享资源
- 线程安全与共享资源
- 线程安全与共享资源
- 线程安全与共享资源
- 线程安全与共享资源
- 线程安全与共享资源
- 线程安全与共享资源
- 线程安全与共享资源
- 6 线程安全与共享资源
- 【java线程安全与共享资源】
- 线程安全与共享资源(线程控制逃逸规则)
- 并发编程六:线程安全与共享资源
- java并发-线程安全与共享资源(4)
- Java并发编程的暗自努力(四)线程安全与共享资源
- SICP 习题2.17 last-pair 找出表的最后一个值
- apache与tomcat负载集群的方法与集群的文件同步问题和图片上传显示问题解决
- React-native开发系列(一)---NavigatorIOS应用
- 作为开发者不可不知的Native App,Web App,Hybrid App等技术的对比
- Can't resolve reference to bean 'dataSource' in parent factory: no parent factory available
- 多线程 2(线程安全与共享资源)
- struts action接收参数的三种方法
- 一念永恒 > 第九十一章 疯狂的北岸
- 一念永恒 > 第九十章 北岸公敌
- Java调用本地接口:java.lang.UnsatisfiedLinkError
- CMake Error: Could not find CMAKE_ROOT !!! CMake has most likely not been installed correctly. Modul
- hello
- Merge k Sorted Lists 归并k个链表
- 为 ECShop 文章添加缩略图