使用condition对象能够对线程业务进行规划和排序。请看以下代码java
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Run { volatile private static int nextPrintWho = 1; private static ReentrantLock lock = new ReentrantLock(); final private static Condition conditionA = lock.newCondition(); final private static Condition conditionB = lock.newCondition(); final private static Condition conditionC = lock.newCondition(); public static void main(String[] args) { Thread thread = new Thread() { @Override public void run() { super.run(); try { lock.lock(); while (nextPrintWho != 1) { conditionA.await(); } for (int i = 0; i < 3; i++) { System.out.println("printA is " + i); } nextPrintWho = 2; conditionB.signalAll(); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { lock.unlock(); } } }; Thread threadb = new Thread() { @Override public void run() { super.run(); try { lock.lock(); while (nextPrintWho != 2) { conditionB.await(); } for (int i = 0; i < 3; i++) { System.out.println("printB is " + i); } nextPrintWho = 3; conditionC.signalAll(); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { lock.unlock(); } } }; Thread threadc = new Thread() { @Override public void run() { super.run(); try { lock.lock(); while (nextPrintWho != 3) { conditionC.await(); } for (int i = 0; i < 3; i++) { System.out.println("printC is " + i); } nextPrintWho = 1; conditionB.signalAll(); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { lock.unlock(); } } }; Thread[] aArray = new Thread[10]; Thread[] bArray = new Thread[10]; Thread[] cArray = new Thread[10]; for (int i =0 ;i <5 ;i++) { aArray[i] = new Thread(thread); bArray[i] = new Thread(threadb); cArray[i] = new Thread(threadc); aArray[i].start(); bArray[i].start(); cArray[i].start(); } } }
输出结果安全
printA is 0 printA is 1 printA is 2 printB is 0 printB is 1 printB is 2 printC is 0 printC is 1 printC is 2 printA is 0 printA is 1 printA is 2 printB is 0 printB is 1 printB is 2 printC is 0 printC is 1 printC is 2 printA is 0 printA is 1 printA is 2 printB is 0 printB is 1 printB is 2 printC is 0 printC is 1 printC is 2
ReentrantLock锁是彻底互斥的锁,即同一时间内只有一个线程执行锁后面的方法,这样作虽然保证了变量的线程安全性,可是效果是很是低下的。因此jdk提供了一种读写锁,在某些不须要操做gong共享变量的状况下彻底能够使用读写锁来提高方法的运行速度。ide
读写锁包含了两个锁,一个是读锁,也称共享锁,一个是写锁,也称排他锁。即多个读锁之间不互斥,写锁和读锁互斥,读锁和读锁互斥。在没有线程执行写入操做的时候,进行读取操做的多个线程均可以获取读锁,写锁只有在得到锁后才能进行写操做。this
请看以下代码线程
public class ReadLock { private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public void read() { try { readWriteLock.readLock().lock(); System.out.println("得到锁---->线程名称是---->"+Thread.currentThread().getName()); Thread.sleep(1000); System.out.println("睡眠苏醒---->线程名称是---->"+Thread.currentThread().getName()); } catch (InterruptedException ex){ ex.printStackTrace(); }finally { readWriteLock.readLock().unlock(); } } } public class ThreadA extends Thread{ private ReadLock readLock ; public ThreadA(ReadLock readLock) { this.readLock = readLock; } @Override public void run() { readLock.read(); } } public class ThreadB extends Thread{ private ReadLock readLock ; public ThreadB(ReadLock readLock) { this.readLock = readLock; } @Override public void run() { readLock.read(); } } public class Run { public static void main(String[] args) { ReadLock lock = new ReadLock(); ThreadA threadA = new ThreadA(lock); threadA.setName("A"); ThreadB threadB = new ThreadB(lock); threadB.setName("B"); threadA.start(); threadB.start(); } }
输出结果是code
得到锁---->线程名称是---->B 得到锁---->线程名称是---->A 睡眠苏醒---->线程名称是---->B 睡眠苏醒---->线程名称是---->A
稍微修改上面的代码对象
public class WriteLock { private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public void read() { try { readWriteLock.writeLock().lock(); System.out.println("得到锁---->线程名称是---->"+Thread.currentThread().getName()); Thread.sleep(1000); System.out.println("睡眠苏醒---->线程名称是---->"+Thread.currentThread().getName()); } catch (InterruptedException ex){ ex.printStackTrace(); }finally { readWriteLock.writeLock().unlock(); } } }
输出结果排序
得到锁---->线程名称是---->A 睡眠苏醒---->线程名称是---->A 得到锁---->线程名称是---->B 睡眠苏醒---->线程名称是---->B
请参考以下代码get
import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLock { private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public void read() { try { readWriteLock.readLock().lock(); System.out.println("读线程得到锁---->线程名称是---->" + Thread.currentThread().getName()); Thread.sleep(1000); System.out.println("读线程睡眠苏醒---->线程名称是---->" + Thread.currentThread().getName()); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { readWriteLock.readLock().unlock(); } } public void write() { try { readWriteLock.writeLock().lock(); System.out.println("写线程得到锁---->线程名称是---->" + Thread.currentThread().getName()); Thread.sleep(1000); System.out.println("写线程睡眠苏醒---->线程名称是---->" + Thread.currentThread().getName()); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { readWriteLock.writeLock().unlock(); } } } public class ThreadA extends Thread{ private ReadWriteLock readLock ; public ThreadA(ReadWriteLock readLock) { this.readLock = readLock; } @Override public void run() { readLock.read(); } } public class ThreadB extends Thread{ private ReadWriteLock readLock ; public ThreadB(ReadWriteLock readLock) { this.readLock = readLock; } @Override public void run() { readLock.write(); } } public class Run { public static void main(String[] args) { ReadWriteLock lock = new ReadWriteLock(); ThreadA threadA = new ThreadA(lock); threadA.setName("A"); ThreadB threadB = new ThreadB(lock); threadB.setName("B"); threadA.start(); threadB.start(); } }
输出结果it
读线程得到锁---->线程名称是---->A 读线程睡眠苏醒---->线程名称是---->A 写线程得到锁---->线程名称是---->B 写线程睡眠苏醒---->线程名称是---->B