读书人

java线程安全有关问题之静态变量、实例

发布时间: 2012-09-19 13:43:53 作者: rapoo

java线程安全问题之静态变量、实例变量、局部变量

? java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同《java并发编程实践》中所说:

Java代码??java线程安全有关问题之静态变量、实例变量、局部变量
  1. /**??
  2. ??*?线程安全问题模拟执行??
  3. ??*??------------------------------??
  4. ??*???????线程1??????|????线程2??
  5. ??*??------------------------------??
  6. ??*???static_i?=?4;??|?等待??
  7. ??*???static_i?=?10;?|?等待??
  8. ??*????等待??????????|?static_i?=?4;??
  9. ??*???static_i?*?2;??|?等待??
  10. ??*??-----------------------------?
  11. ?*?*/??
  12. public?class?Test?implements?Runnable??
  13. {??
  14. ????private?static?int?static_i;//静态变量???
  15. ??????
  16. ????public?void?run()??
  17. ????{??
  18. ????????static_i?=?4;??
  19. ????????System.out.println("["?+?Thread.currentThread().getName()??
  20. ????????????????+?"]获取static_i?的值:"?+?static_i);??
  21. ????????static_i?=?10;??
  22. ????????System.out.println("["?+?Thread.currentThread().getName()??
  23. ????????????????+?"]获取static_i*3的值:"?+?static_i?*?2);??
  24. ????}??
  25. ??????
  26. ????public?static?void?main(String[]?args)??
  27. ????{??
  28. ????????Test?t?=?new?Test();??
  29. ????????//启动尽量多的线程才能很容易的模拟问题???
  30. ????????for?(int?i?=?0;?i?<?3000;?i++)??
  31. ????????{??
  32. ????????????//t可以换成new?Test(),保证每个线程都在不同的对象中执行,结果一样???
  33. ????????????new?Thread(t,?"线程"?+?i).start();??
  34. ????????}??
  35. ????}??
  36. }??

?

?

?

根据代码注释中模拟的情况,当线程1执行了static_i = 4;??static_i = 10; 后,线程2获得执行权,static_i = 4;?然后当线程1获得执行权执行static_i * 2;? 必然输出结果4*2=8,按照这个模拟,我们可能会在控制台看到输出为8的结果。

Java代码??java线程安全有关问题之静态变量、实例变量、局部变量
  1. public?class?Test?implements?Runnable??
  2. {??
  3. ????private?int?instance_i;//实例变量??
  4. ??????
  5. ????public?void?run()??
  6. ????{??
  7. ????????instance_i?=?4;??
  8. ????????System.out.println("["?+?Thread.currentThread().getName()??
  9. ????????????????+?"]获取instance_i?的值:"?+?instance_i);??
  10. ????????instance_i?=?10;??
  11. ????????System.out.println("["?+?Thread.currentThread().getName()??
  12. ????????????????+?"]获取instance_i*3的值:"?+?instance_i?*?2);??
  13. ????}??
  14. ??????
  15. ????public?static?void?main(String[]?args)??
  16. ????{??
  17. ????????Test?t?=?new?Test();??
  18. ????????//启动尽量多的线程才能很容易的模拟问题???
  19. ????????for?(int?i?=?0;?i?<?3000;?i++)??
  20. ????????{??
  21. ????????????//每个线程对在对象t中运行,模拟单例情况??
  22. ????????????new?Thread(t,?"线程"?+?i).start();??
  23. ????????}??
  24. ????}??
  25. }??

?

?

按照本文开头的分析,犹如静态变量那样,每个线程都在修改同一个对象的实例变量,肯定会出现线程安全问题。

写道

[线程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代码??java线程安全有关问题之静态变量、实例变量、局部变量
  1. public?class?Test?implements?Runnable??
  2. {??
  3. ????public?void?run()??
  4. ????{??
  5. ????????int?local_i?=?4;??
  6. ????????System.out.println("["?+?Thread.currentThread().getName()??
  7. ????????????????+?"]获取local_i?的值:"?+?local_i);??
  8. ????????local_i?=?10;??
  9. ????????System.out.println("["?+?Thread.currentThread().getName()??
  10. ????????????????+?"]获取local_i*2的值:"?+?local_i?*?2);??
  11. ????}??
  12. ??????
  13. ????public?static?void?main(String[]?args)??
  14. ????{??
  15. ????????Test?t?=?new?Test();??
  16. ????????//启动尽量多的线程才能很容易的模拟问题??
  17. ????????for?(int?i?=?0;?i?<?3000;?i++)??
  18. ????????{??
  19. ????????????//每个线程对在对象t中运行,模拟单例情况???
  20. ????????????new?Thread(t,?"线程"?+?i).start();??
  21. ????????}??
  22. ????}??
  23. }??

?

?

控制台没有出现异常数据。

?

---------------------------

以上只是通过简单的实例来展示静态变量、实例变量、局部变量等的线程安全问题,

并未进行底层的分析,下一篇将对线程问题的底层进行剖析。

?

读书人网 >编程

热点推荐