Java线程学习笔记之线程安全与不安全
2017-02-16 11:20
465 查看
在JDK API,有很多类上面都写着是线程安全或者线程不安全,比如StringBuilder就是线程不安全的类,在多线程的情况下,如果需要同步,则建议使用StringBuffer。
存在成员变量的类用于多线程时是不安全的,不安全体现在这个成员变量可能发生非原子性的操作,而变量定义在方法内也就是局部变量是线程安全的。在日常开发中,通常需要考虑成员变量或者说全局变量在多线程环境下,是否会引发一些问题。以下是示例:
创建一个线程不安全的类:
创建多线程并执行
这里,我们想要的结果是输出的值是一样的55
而实际上的输出结果是(会有不同的输出结果,反正不会是上面的):
完全乱掉,也就是说,所有的线程都在任意时刻读取和修改成员变量num的值,而且没有同步。也可以说这种错误是由于成员变量造成的
当我们把Count类的成员变量num变为方法变量的时候:
结果
或者我们把runnable的成员变量变为方法变量
输出都符合我们的预期。
存在成员变量的类用于多线程时是不安全的,不安全体现在这个成员变量可能发生非原子性的操作,而变量定义在方法内也就是局部变量是线程安全的。在日常开发中,通常需要考虑成员变量或者说全局变量在多线程环境下,是否会引发一些问题。以下是示例:
创建一个线程不安全的类:
public class Count { private int num;//成员变量 public void count() { for(int i=1;i<=10;i++){ num+=i; } System.out.println("线程:"+Thread.currentThread().getName()+";数据:"+num); } }
创建多线程并执行
public class ThreadSecurityTest { public static void main(String[] args){ Runnable runnable = new Runnable() { Count count = new Count(); @Override public void run() { count.count(); } }; for(int i=0;i<10;i++){ new Thread(runnable).start(); } } }
这里,我们想要的结果是输出的值是一样的55
而实际上的输出结果是(会有不同的输出结果,反正不会是上面的):
线程:Thread-0;数据:55 线程:Thread-3;数据:165 线程:Thread-2;数据:275 线程:Thread-9;数据:495 线程:Thread-5;数据:550 线程:Thread-4;数据:220 线程:Thread-1;数据:165 线程:Thread-6;数据:330 线程:Thread-8;数据:440 线程:Thread-7;数据:385
完全乱掉,也就是说,所有的线程都在任意时刻读取和修改成员变量num的值,而且没有同步。也可以说这种错误是由于成员变量造成的
当我们把Count类的成员变量num变为方法变量的时候:
public class Count { //private int num; public synchronized void count() { int num = 0; for(int i=1;i<=10;i++){ num+=i; } System.out.println("线程:"+Thread.currentThread().getName()+";数据:"+num); } }
结果
线程:Thread-0;数据:55 线程:Thread-3;数据:55 线程:Thread-4;数据:55 线程:Thread-2;数据:55 线程:Thread-1;数据:55 线程:Thread-7;数据:55 线程:Thread-9;数据:55 线程:Thread-8;数据:55 线程:Thread-6;数据:55 线程:Thread-5;数据:55
或者我们把runnable的成员变量变为方法变量
线程:Thread-4;数据:55 线程:Thread-2;数据:55 线程:Thread-9;数据:55 线程:Thread-7;数据:55 线程:Thread-3;数据:55 线程:Thread-0;数据:55 线程:Thread-1;数据:55 线程:Thread-5;数据:55 线程:Thread-6;数据:55 线程:Thread-8;数据:55
输出都符合我们的预期。
相关文章推荐
- 扩展欧几里得专题(一)
- maven项目下没有webContext目录怎么办
- JDK1.8源码阅读之——String,StringBuffer, StringBuilder
- Java Web开发之环境搭建
- JAVA 静态内部类和非静态内部类的区别
- 算法笔记_031:计算中值和选择问题(Java)
- 使用Eclipse的Working Set,界面清爽多了
- java获取某个范围内的一个随机数
- Spring MVC拦截器教程——慕课网
- springmvc常用注解标签详解
- 深入理解java虚拟机阅读后精华摘要
- Eclipse注释模板设置方法
- maven环境变量的配置及+eclipse的配置使用
- Restful风格API接口开发springMVC篇
- Spring注解@Component、@Repository、@Service、@Controller区别
- 【Java】利用位运算原来加密可以很简单
- java日期操作
- 线程安全、非线程安全
- Java三大框架
- java String类常用方法练习小结