锁定老帖子 主题:Java中同步代码块的疑惑
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-04-24
最后修改:2012-04-24
在Java同步代码块中可以指定一个object作为同步锁,但是当我指定的object不一样的时候,产生了不一样的输出,不知道什么原因,下面是示例代码:
import java.util.logging.Level; import java.util.logging.Logger; class CallMe { public void demoMethod(String message) { try { System.out.print("{"); Thread.sleep(1); System.out.print(message); Thread.sleep(1); System.out.println("}"); } catch (InterruptedException ex) { Logger.getLogger(CallMe.class.getName()).log(Level.SEVERE, null, ex); } } } class NewThread extends Thread { CallMe callme; String name; CallMe callme1 = new CallMe(); public NewThread(String x, CallMe callme) { this.callme = callme; name = x; } public void run() { synchronized (callme1) { callme.demoMethod(name); } } } public class ThreadDemo { public static void main(String args[]) throws InterruptedException { CallMe callme = new CallMe(); NewThread nt1 = new NewThread("one", callme); NewThread nt2 = new NewThread("two", callme); NewThread nt3 = new NewThread("three", callme); nt1.start(); nt2.start(); nt3.start(); nt1.join(); nt2.join(); nt3.join(); } } 输出结果为:
{{{threeonetwo} } }
但是对于下面的代码(注意只有那个synchronized(callme)不一样):
import java.util.logging.Level; import java.util.logging.Logger; class CallMe { public void demoMethod(String message) { try { System.out.print("{"); Thread.sleep(1); System.out.print(message); Thread.sleep(1); System.out.println("}"); } catch (InterruptedException ex) { Logger.getLogger(CallMe.class.getName()).log(Level.SEVERE, null, ex); } } } class NewThread extends Thread { CallMe callme; String name; CallMe callme1 = new CallMe(); public NewThread(String x, CallMe callme) { this.callme = callme; name = x; } public void run() { synchronized (callme) { callme.demoMethod(name); } } } public class ThreadDemo { public static void main(String args[]) throws InterruptedException { CallMe callme = new CallMe(); NewThread nt1 = new NewThread("one", callme); NewThread nt2 = new NewThread("two", callme); NewThread nt3 = new NewThread("three", callme); nt1.start(); nt2.start(); nt3.start(); nt1.join(); nt2.join(); nt3.join(); } } 输出结果为:
{one} {two} {three}
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-04-24
不同的对象,不同的实例,不同的锁。当前对象作为锁。
|
|
返回顶楼 | |
发表时间:2012-04-25
最后修改:2012-04-25
锁同一个对象才能同步
|
|
返回顶楼 | |
发表时间:2012-04-28
第一块代码,不存在锁资源竞争,就是说执行顺序随机。
第二块,竞争同一资源。 |
|
返回顶楼 | |
发表时间:2012-04-28
第一段代码21行,加static限制,两段代码的输出就一致了
|
|
返回顶楼 | |
发表时间:2012-04-29
前者是错误用法
|
|
返回顶楼 | |
发表时间:2012-04-29
第一段代码中,每一个线程使用中,使用的锁都不同,所以不存在资源竞争,也就不存在互斥,所以不存在同步;第二段代码中,三个线程使用的是同一个锁,线程执行的时候,对于同步块会有互斥现象,所以可以实现同步。
|
|
返回顶楼 | |
发表时间:2012-05-03
第一个代码块中,callme1是实例变量,每一个对象都有他自己的实现,所以用它做锁没有效果;
第二个代码块中,三个对象共享一个callme,所以用它做锁会产生竞争. |
|
返回顶楼 | |
发表时间:2012-05-03
同意
humor200 的说法 |
|
返回顶楼 | |
发表时间:2012-05-03
my_queen 写道 第一个代码块中,callme1是实例变量,每一个对象都有他自己的实现,所以用它做锁没有效果;
第二个代码块中,三个对象共享一个callme,所以用它做锁会产生竞争. 恩, 但是LZ的这个例子对输出的顺序根本没有任何限制,两个例子的输出都是无顺序保证的 |
|
返回顶楼 | |