个人理解…
不可重入:如果一个线程1已经持doSomething2(),另外个线程2进入doSomething1(),就必须等线程2释放锁;
Object object1 = new Object();
Object object2 = new Object();
public void doSomething1() {
synchronized(object1)
{
System.out.printf("%s: Going to 2\n", Thread.currentThread().getName());
doSomething2();
}
}
public void doSomething2() {
synchronized(object2)
{
try {
System.out.printf("%s: Doing 2\n", Thread.currentThread().getName());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Thread-1: Doing 2
Thread-13: Going to 2
Thread-13: Doing 2
Thread-12: Doing 2
Thread-24: Going to 2
Thread-11: Doing 2
Thread-10: Doing 2
Thread-9: Doing 2
重入锁:进入了doSomething1()可以马上执行doSomething2()。 ReentrantLock的lock方法也是这样可以重入的。
public void doSomething1() { synchronized(this) { System.out.printf("%s: Going to 2\n", Thread.currentThread().getName()); doSomething2(); } } public void doSomething2() { synchronized(this) { try { System.out.printf("%s: Doing 2\n", Thread.currentThread().getName()); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }
结果
Thread-24: Going to 2
Thread-24: Doing 2
Thread-23: Going to 2
Thread-23: Doing 2
Thread-22: Going to 2
Thread-22: Doing 2
完整代码:
public class TestReentrantsLock { Object object1 = new Object(); Object object2 = new Object(); public void doSomething1() { synchronized(object1) { System.out.printf("%s: Going to 2\n", Thread.currentThread().getName()); doSomething2(); } } public void doSomething2() { synchronized(object2) { try { System.out.printf("%s: Doing 2\n", Thread.currentThread().getName()); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { TestReentrantsLock lock = new TestReentrantsLock(); TestDo job = new TestDo(lock); TestDo2 job2 = new TestDo2(lock); for (int i = 0; i < 12; i++) { Thread t = new Thread(job2); t.start(); } for (int i = 0; i < 12; i++) { Thread t = new Thread(job); t.start(); } } } class TestDo implements Runnable { private TestReentrantsLock lock; public TestDo(TestReentrantsLock lock) { this.lock = lock; } @Override public void run() { lock.doSomething1(); } } class TestDo2 implements Runnable { private TestReentrantsLock lock; public TestDo2(TestReentrantsLock lock) { this.lock = lock; } @Override public void run() { lock.doSomething2(); } }