加锁和解锁
我们来看下ReentrantLock的基本用法
ThreadDomain35类
public class ThreadDomain35 { private Lock lock = new ReentrantLock(); public void testMethod() { try { lock.lock(); for (int i = 0; i < 2; i++) { System.out.println("ThreadName = " + Thread.currentThread().getName() + ", i = " + i); } } finally { lock.unlock(); } } }
线程和main方法
public class MyThread35 extends Thread { private ThreadDomain35 td; public MyThread35(ThreadDomain35 td) { this.td = td; } public void run() { td.testMethod(); } public static void main(String[] args) { ThreadDomain35 td = new ThreadDomain35(); MyThread35 mt0 = new MyThread35(td); MyThread35 mt1 = new MyThread35(td); MyThread35 mt2 = new MyThread35(td); mt0.start(); mt1.start(); mt2.start(); } }
输出结果
ThreadName = Thread-2, i = 0 ThreadName = Thread-2, i = 1 ThreadName = Thread-0, i = 0 ThreadName = Thread-0, i = 1 ThreadName = Thread-1, i = 0 ThreadName = Thread-1, i = 1
一个线程必须执行完才能执行下一个线程,说明ReentrantLock可以加锁。
ReentrantLock持有的对象监视器和synchronized不同
ThreadDomain37类,methodB用synchronized修饰
public class ThreadDomain37 { private Lock lock = new ReentrantLock(); public void methodA() { try { lock.lock(); System.out.println("MethodA begin ThreadName = " + Thread.currentThread().getName()); Thread.sleep(5000); System.out.println("MethodA end ThreadName = " + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public synchronized void methodB() { System.out.println("MethodB begin ThreadName = " + Thread.currentThread().getName()); System.out.println("MethodB begin ThreadName = " + Thread.currentThread().getName()); } }
MyThread37_0类
public class MyThread37_0 extends Thread { private ThreadDomain37 td; public MyThread37_0(ThreadDomain37 td) { this.td = td; } public void run() { td.methodA(); } }
MyThread37_1类
public class MyThread37_1 extends Thread { private ThreadDomain37 td; public MyThread37_1(ThreadDomain37 td) { this.td = td; } public void run() { td.methodB(); } }
MyThread37_main方法
public class MyThread37_main { public static void main(String[] args) { ThreadDomain37 td = new ThreadDomain37(); MyThread37_0 mt0 = new MyThread37_0(td); MyThread37_1 mt1 = new MyThread37_1(td); mt0.start(); mt1.start(); } }
运行结果如下
MethodA begin ThreadName = Thread-0 MethodB begin ThreadName = Thread-1 MethodB begin ThreadName = Thread-1 MethodA end ThreadName = Thread-0
加了synchronized依然是异步执行,说明Reentra本文来源gao@!dai!ma.com搞$$代^@码5网@ntLock和synchronized持有的对象监视器不同。ReentrantLock需要手动加锁和释放锁。
Condition
基本用法
synchronized与wait()和nitofy()/notifyAll()方法可以实现等待/唤醒模型,ReentrantLock同样可以,需要借助Condition的await()和signal/signalAll(),await()释放锁。