多线程同步中不同锁对象导致执行行为差异的原因咨询
多线程同步中不同锁对象导致执行行为差异的原因咨询
嘿,这个问题问到点子上了,咱们把两种锁的本质差异掰扯清楚就明白啦:
1. 用静态的lock对象时为啥能顺序执行?
lock是MyClass的静态私有成员,这意味着整个MyClass类在JVM里只有这一个lock实例——不管你new了多少个Worker对象,所有线程在进入synchronized块时,争抢的都是这同一个锁资源。
同一时间只有一个线程能成功获取这个锁,执行块里的打印和runCount自增操作,其他线程都得等着锁被释放才能继续。所以每个线程的输出都是依次来的,不会出现重叠。
2. 用Worker类里的lock2对象时为啥会重叠?
lock2是Worker类的非静态成员,这意味着你每new一个Worker对象,就会生成一个全新的lock2实例。现在你启动了5个线程,每个线程对应一个独立的Worker对象,那每个线程持有的都是属于自己的lock2锁。
说白了就是每个线程在给自己“上锁”,完全不会和其他线程产生锁竞争!所以多个线程可以同时进入各自的synchronized块执行代码,打印操作自然就会出现互相重叠的情况了。
另外补充一句:你代码里的runCount也是每个Worker实例自己的变量,不过这里同步行为的核心差异,根源还是锁对象的共享性——只有当多个线程争抢同一个锁时,同步机制才能起到“串行执行”的作用。
class MyClass { private static Object lock = new Object(); public static void main(String[] args) { (new Thread(new Worker(),"Thread 1")).start(); (new Thread(new Worker(),"Thread 2")).start(); (new Thread(new Worker(),"Thread 3")).start(); (new Thread(new Worker(),"Thread 4")).start(); (new Thread(new Worker(),"Thread 5")).start(); } private static class Worker implements Runnable{ private int runCount = 1; private Object lock2 = new Object(); @Override public void run() { for(int i = 0; i < 100; i++){ synchronized (lock){ System.out.format("s" + "%s: runCount = %d\n", Thread.currentThread().getName(), runCount++); } } } } }
备注:内容来源于stack exchange,提问作者Juan Pollacchi
相关产品推荐
相关产品推荐

