Lock锁住的是什么
通常lock对象都是final的,它锁住的是mLock.lock()和mLock.unlock()之间的代码块。也就是说所有使用了同一mLock对象的锁块之间是互斥的。
import java.util.concurrent.locks.ReentrantLock; public class LockTest{ public static void main(String[] args){ final ReentrantLock mLock = new ReentrantLock(); Thread t = new Thread(){ public void run(){ for(int i = 0; i < 3; i++){ try{ mLock.lock(); System.out.println("thread 2 running i = " + i + " start"); sleep(3000); System.out.println("thread 2 running i = " + i + " end"); }catch(Exception e){ }finally{ mLock.unlock(); } } } }; t.start(); for(int i = 0; i < 3; i++){ try{ mLock.lock(); System.out.println("thread main running i = " + i + " start"); Thread.sleep(2000); System.out.println("thread main running i = " + i + " end"); }catch(Exception e){ }finally{ mLock.unlock(); } } } }
如上代码段,注释掉两个mLock.lock(),执行结果如下:
thread main running i = 0 start thread 2 running i = 0 start thread main running i = 0 end thread main running i = 1 start thread 2 running i = 0 end thread 2 running i = 1 start thread main running i = 1 end thread main running i = 2 start thread 2 running i = 1 end thread 2 running i = 2 start thread main running i = 2 end thread 2 running i = 2 end
线程是交替执行的,如果代码区内有共享内容,将会出现线程安全问题。
有锁的情况下,执行结果如下:
thread main running i = 0 start thread main running i = 0 end thread main running i = 1 start thread main running i = 1 end thread main running i = 2 start thread main running i = 2 end thread 2 running i = 0 start thread 2 running i = 0 end thread 2 running i = 1 start thread 2 running i = 1 end thread 2 running i = 2 start thread 2 running i = 2 end
不会同时访问锁块之间的内容。
当使用公平锁——mLock =new ReentrantLock(true),执行结果如下:
thread main running i = 0 start thread main running i = 0 end thread 2 running i = 0 start thread 2 running i = 0 end thread main running i = 1 start thread main running i = 1 end thread 2 running i = 1 start thread 2 running i = 1 end thread main running i = 2 start thread main running i = 2 end thread 2 running i = 2 start thread 2 running i = 2 end
《Java并发编程从入门到精通》显示锁Lock和ReentrantLock