原文:
http://huagenli.iteye.com/blog/511414 最后的代码如下:
/**=============================================================================
* 文件:ThreadDemo_06.java
* 描述:为什么造成线程的不同步。
* =============================================================================
*/
1. class ThreadDemo extends Thread{
2. //共享一个静态数据成员
3. private static String szShareData = "";
4.
5. ThreadDemo(){
6. }
7.
8. ThreadDemo(String szName){
9. super(szName);
10. }
11.
12. public void run(){
13. // 为了更清楚地看到不正确的结果,这里放一个大的循环
14. for (int i = 0; i < 50; i++){
15. if (this.getName().equals("Thread1")){
16. synchronized(szShareData){
17. szShareData = "这是第 1 个线程";
18. // 为了演示产生的问题,这里设置一次睡眠
19. try{
20. Thread.sleep((int)Math.random() * 100);
21. catch(InterruptedException e){
22. }
23. // 输出结果
24. System.out.println(this.getName() + ":" + szShareData);
25. }
26. }else if (this.getName().equals("Thread2")){
27. synchronized(szShareData){
28. szShareData = "这是第 1 个线程";
29. // 为了演示产生的问题,这里设置一次睡眠
30. try{
31. Thread.sleep((int)Math.random() * 100);
32. catch(InterruptedException e){
33. }
34. // 输出结果
35. System.out.println(this.getName() + ":" + szShareData);
36. }
37. }
38. }
39. }
40.
41. class ThreadMain{
42. public static void main(String argv[]){
43. ThreadDemo th1 = new ThreadDemo("Thread1");
44. ThreadDemo th2 = new ThreadDemo("Thread2");
45.
46. th1.start();
47. th2.start();
48. }
49. }
并且在最后提出了问题:
这段代码的共享成员是一个类中的静态成员,按理说,这里进入共享代码时得到的锁应该是同样的锁,而实际上以上程序的输入却是不同步的,为什么呢??
...按理说,这里进入共享代码时得到的锁应该是同样的锁...这句话说得太隐晦,是说到得是同一把锁,还是说得到得都是对象锁? 刚学java同步两周,我大胆的来解决最后的问题:
synchronized(YourClassName.class ):当前线程得到的是YourClassName的Class锁,那么在当前线程释放此Class锁之前,别的线程没有机会访问YourClassName里的一切。
我翻阅了几本书,没有得到以下明文,下面是我的
推断:
synchronized(private static 实例变量):当前线程得到的是访问private static 实例变量的对象的锁。所以thread1、thread2得到的是不同的对象锁。假设thread1运行到最后代码中的16行,此时得到的是对象一的锁,然后程序改变了szShareData的引用(引用了别的地址),接着小睡片刻; thread2抢占时间片,执行到16行,得到对象二的锁,改变了szShareData的引用,小睡片刻;thread1抢占时间片(这是假设,thread1有可能在N个时间片后执行),执行输出结果,其实输出的是thread2改变后的szShareData,这样就出现了紊乱。如果观察的不是很明显,可以把sleep改成这样:Thread.sleep(2)。
改正:把synchronized(private static 实例变量)改成synchronized(YourClassName.class );或者把方法(里面对static实例变量访问)改写成public static synchronized的,这样获得的锁与synchronized(YourClassName.class )获得的是
同一把锁。^..^ Thread.sleep(2)期间线程不会释放锁。
结论:synchronized(private static 实例变量):当前线程得到的是访问private static 实例变量的对象的锁。
分享到:
相关推荐
Java是世界上最流行的编程语言之一,尤其在企业级应用开发领域占据主导地位。这份"java笔记与java核心内容解读"集合了网上广泛讨论的Java知识,旨在...无论你是初涉Java的新手还是寻求进阶的开发者,都能从中受益匪浅。
总的来说,《俄罗斯方块JAVA版》项目不仅是一个有趣的游戏,也是一个学习JAVA多线程编程和游戏开发的实战案例。开发者可以从中学习到如何利用JAVA的并发特性来构建实时系统,以及如何通过对象和类的设计实现复杂逻辑...
总之,《Java for Programmers 2nd Edition》是一本全面且深入的Java教程,无论你是初涉Java的世界,还是希望提升自己的编程能力,这本书都能提供丰富的知识和实用的技巧。结合提供的源代码,你将能够更好地掌握Java...
总的来说,《Java编程精选集锦》是一本全面且实用的Java学习资料,无论你是初涉Java编程的新手,还是寻求进阶的开发者,都能从中受益。通过深入阅读和实践,你将能够熟练掌握Java编程,并具备在J2EE平台上构建复杂...
此外,Java多线程编程是并发处理的关键。通过实现Runnable接口或继承Thread类,你可以创建并运行多个线程,理解线程同步和互斥的概念,以及synchronized关键字的使用,对于编写高效的并发程序至关重要。 在Java的...
总而言之,《Java网络高级编程》这本书全面覆盖了Java在网络编程领域的各个方面,无论你是希望提升现有技能的开发者,还是初涉网络编程的新手,都能从中获益匪浅。通过深入学习,你将能够利用Java的强大功能,构建出...
Java作为一门广泛使用的编程语言,其基础知识和实践经验对于初学者来说至关重要。...无论你是初涉Java的新人,还是寻求巩固基础的开发者,这个精选教程都能提供宝贵的资源,助你在Java的世界里稳步前行。
Java和JSP是Web开发领域...总的来说,"Java&&JSP最全资料"是一份宝贵的资源,无论你是初涉Java和JSP,还是寻求进阶提升,都能从中受益。通过深入学习和实践,你将能够熟练掌握这两种技术,从而在Web开发领域游刃有余。
总的来说,《Java2参考大全》(第四版)是一本内容全面、深度适中的Java编程指南,无论你是初涉Java的新手,还是寻求提升的老兵,都能在这本书中找到你需要的知识。通过阅读并实践书中的内容,你将能够熟练掌握Java...
【Java编程语言基础】 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(现已被Oracle收购)于1995年推出。...无论你是初涉Java世界还是寻求深入理解,这个压缩包都能提供有价值的资源。
总之,《JAVA入门、提高与精通》这份教材详尽地介绍了Java编程的各个方面,从基础到高级,适合不同层次的学习者,无论你是初涉编程的新手还是寻求提升的开发者,都能从中受益。通过学习,你将能够熟练掌握Java技术,...
Java及Java EE面试大全主要涵盖了Java语言的...对于初涉Java领域的求职者,理解并掌握以上知识点是面试成功的关键。在准备面试时,不仅要理解概念,还要能编写代码实现相关功能,同时对实际项目经验的积累也很重要。
在本资源中,我们主要探讨的是使用Java编程语言进行游戏开发的一个实例——“打飞机”游戏。...因此,无论你是初涉Java游戏开发,还是希望提升自己的技能,这个“打飞机”游戏项目都是一个值得深入探索的学习资源。
作为初涉游戏开发的尝试,它展示了Java在游戏开发领域的应用潜力。下面将详细介绍这款游戏中涉及的主要Java技术和相关知识点。 1. **Java基础知识**:Java是一种跨平台的面向对象的编程语言,它的“一次编写,到处...
这份压缩包中的中文文章,无疑为JAVA学习者提供了一个全面且深入的学习路径,无论你是初涉JAVA的新手,还是寻求提升的开发者,都能从中受益。通过系统地学习和实践,可以有效地提高JAVA编程技能,更好地应对实际开发...
Java基础是编程世界的基石,尤其是对于那些初涉这个领域的人来说。Java是一种面向对象的、跨平台的编程语言,由Sun Microsystems(现为Oracle Corporation的一部分)于1995年发布。它的设计目标是“简单、健壮、安全...
《Java葵花宝典——各种问题详细解答》 ...无论你是初涉Java的新手,还是希望巩固基础的开发者,都可以从中受益。通过深入学习和实践,你将能够熟练掌握Java,解决各种实际问题,成为一名出色的Java工程师。
此外,Java的多线程特性也非常重要,因为它允许游戏同时处理多个任务,如游戏逻辑、渲染和用户输入,确保游戏流畅运行。 游戏的实现可能涉及到以下几个关键知识点: 1. **面向对象编程**:Java是一种面向对象的...
在儿童教育领域,游戏化学习已经逐渐成为一种有效的教学手段,而Java平台因其跨平台、易学易用的...无论你是经验丰富的开发者还是初涉此领域的新人,都能从中获益,为打造富有创新和教育价值的儿童游戏奠定坚实基础。