java线程安全有关问题之静态变量、实例变量、局部变量
java线程安全问题之静态变量、实例变量、局部变量? java多线程编程中,存在很多线程安全问题,至于什么是线程
java线程安全问题之静态变量、实例变量、局部变量
? java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同《java并发编程实践》中所说:
Java代码??

- /**??
- ??*?线程安全问题模拟执行??
- ??*??------------------------------??
- ??*???????线程1??????|????线程2??
- ??*??------------------------------??
- ??*???static_i?=?4;??|?等待??
- ??*???static_i?=?10;?|?等待??
- ??*????等待??????????|?static_i?=?4;??
- ??*???static_i?*?2;??|?等待??
- ??*??-----------------------------?
- ?*?*/??
- public?class?Test?implements?Runnable??
- {??
- ????private?static?int?static_i;//静态变量???
- ??????
- ????public?void?run()??
- ????{??
- ????????static_i?=?4;??
- ????????System.out.println("["?+?Thread.currentThread().getName()??
- ????????????????+?"]获取static_i?的值:"?+?static_i);??
- ????????static_i?=?10;??
- ????????System.out.println("["?+?Thread.currentThread().getName()??
- ????????????????+?"]获取static_i*3的值:"?+?static_i?*?2);??
- ????}??
- ??????
- ????public?static?void?main(String[]?args)??
- ????{??
- ????????Test?t?=?new?Test();??
- ????????//启动尽量多的线程才能很容易的模拟问题???
- ????????for?(int?i?=?0;?i?<?3000;?i++)??
- ????????{??
- ????????????//t可以换成new?Test(),保证每个线程都在不同的对象中执行,结果一样???
- ????????????new?Thread(t,?"线程"?+?i).start();??
- ????????}??
- ????}??
- }??
?
?
?
根据代码注释中模拟的情况,当线程1执行了static_i = 4;??static_i = 10; 后,线程2获得执行权,static_i = 4;?然后当线程1获得执行权执行static_i * 2;? 必然输出结果4*2=8,按照这个模拟,我们可能会在控制台看到输出为8的结果。
Java代码??

- public?class?Test?implements?Runnable??
- {??
- ????private?int?instance_i;//实例变量??
- ??????
- ????public?void?run()??
- ????{??
- ????????instance_i?=?4;??
- ????????System.out.println("["?+?Thread.currentThread().getName()??
- ????????????????+?"]获取instance_i?的值:"?+?instance_i);??
- ????????instance_i?=?10;??
- ????????System.out.println("["?+?Thread.currentThread().getName()??
- ????????????????+?"]获取instance_i*3的值:"?+?instance_i?*?2);??
- ????}??
- ??????
- ????public?static?void?main(String[]?args)??
- ????{??
- ????????Test?t?=?new?Test();??
- ????????//启动尽量多的线程才能很容易的模拟问题???
- ????????for?(int?i?=?0;?i?<?3000;?i++)??
- ????????{??
- ????????????//每个线程对在对象t中运行,模拟单例情况??
- ????????????new?Thread(t,?"线程"?+?i).start();??
- ????????}??
- ????}??
- }??
?
?
按照本文开头的分析,犹如静态变量那样,每个线程都在修改同一个对象的实例变量,肯定会出现线程安全问题。
写道
[线程66]获取instance_i 的值:10?
[线程33]获取instance_i*2的值:20?
[线程67]获取instance_i 的值:4?
[线程34]获取instance_i*2的值:8?
[线程35]获取instance_i*2的值:20?
[线程68]获取instance_i 的值:4
?
看红色字体,可知单例情况下,实例变量线程非安全。
?
将new Thread(t, "线程" + i).start();改成new Thread(new Test(), "线程" + i).start();模拟非单例情况,会发现不存在线程安全问题。
?
?
局部变量线程安全问题模拟:
----------------------------------------------
?
Java代码??

- public?class?Test?implements?Runnable??
- {??
- ????public?void?run()??
- ????{??
- ????????int?local_i?=?4;??
- ????????System.out.println("["?+?Thread.currentThread().getName()??
- ????????????????+?"]获取local_i?的值:"?+?local_i);??
- ????????local_i?=?10;??
- ????????System.out.println("["?+?Thread.currentThread().getName()??
- ????????????????+?"]获取local_i*2的值:"?+?local_i?*?2);??
- ????}??
- ??????
- ????public?static?void?main(String[]?args)??
- ????{??
- ????????Test?t?=?new?Test();??
- ????????//启动尽量多的线程才能很容易的模拟问题??
- ????????for?(int?i?=?0;?i?<?3000;?i++)??
- ????????{??
- ????????????//每个线程对在对象t中运行,模拟单例情况???
- ????????????new?Thread(t,?"线程"?+?i).start();??
- ????????}??
- ????}??
- }??
?
?
控制台没有出现异常数据。
?
---------------------------
以上只是通过简单的实例来展示静态变量、实例变量、局部变量等的线程安全问题,
并未进行底层的分析,下一篇将对线程问题的底层进行剖析。
?