一、使用Conditiuon实现顺序执行。
condition对象可以对线程执行的业务进行排序规则。
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class RunCondition { volatile private static int nextPrintWho=1; private static ReentrantLock lock =new ReentrantLock(); private static Condition conditionA =lock.newCondition(); private static Condition conditionB =lock.newCondition(); private static Condition conditionC =lock.newCondition(); public static void main(String[] args) { Thread threadA = 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("threadA "+(i+1)); } nextPrintWho=2; conditionB.signalAll(); } catch (InterruptedException e) { e.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("threadB "+(i+1)); } nextPrintWho=3; conditionC.signalAll(); } catch (InterruptedException e) { e.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("threadC "+(i+1)); } nextPrintWho=1; conditionA.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } }; Thread[] t1 = new Thread[5]; Thread[] t2 = new Thread[5]; Thread[] t3 = new Thread[5]; for(int i=0;i<5;i++){ t1[i]=new Thread(threadA); t2[i]=new Thread(threadB); t3[i]=new Thread(threadC); t1[i].start(); t2[i].start(); t3[i].start(); } } }
threadA 1 threadA 2 threadA 3 threadB 1 threadB 2 threadB 3 threadC 1 threadC 2 threadC 3 threadA 1 threadA 2 threadA 3 threadB 1 threadB 2 threadB 3 threadC 1 threadC 2 threadC 3 threadA 1 threadA 2 threadA 3 threadB 1 threadB 2 threadB 3 threadC 1 threadC 2 threadC 3 threadA 1 threadA 2 threadA 3 threadB 1 threadB 2 threadB 3 threadC 1 threadC 2 threadC 3 threadA 1 threadA 2 threadA 3 threadB 1 threadB 2 threadB 3 threadC 1 threadC 2 threadC 3
难点:分析执行顺序的原因。
由于while 的关系,每次只有一个线程执行,另外两个wainting
二、使用ReentrantReadWriteLock类
ReentrantLock 类具有完全互斥排他的效果,即一时间只有一个线程
在执行ReentrantLock.lock()方法后面的任务。
这样做虽然保证了实例的线程安全,但是效率趋确是非常低下,所以,jdk提供了一种
读写锁ReentrantReadWriteLock 类,用它可以加快运行效率,在某一些不需要
操作实例变量的方法中,完全可以使用读写锁ReentrantReadWriteLock来
提升该方法的代码运行效率。
读写锁也有两个锁,一个是读操作相关的锁,也叫共享锁。
另一个是写相关的锁,也叫排他锁。也就是多个读锁之间不排斥
而多个写锁之间会排斥,读和写锁也会排斥。
同一时间多个锁读操作的可以都执行,写操作只有一个执行。
(一)ReentrantReadWriteLock类 使用,读读共享。
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Service14 { private ReentrantReadWriteLock lock =new ReentrantReadWriteLock(); public void read(){ try { lock.readLock().lock(); System.out.println("获得读锁 "+Thread.currentThread().getName()+ " 时间 "+ System.currentTimeMillis()); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.readLock().unlock(); } } }

package com.it.po.thread11.thread11_1; public class Run14 { public static void main(String[] args) throws InterruptedException { Service14 service= new Service14(); MyThread3_1 t1 = new MyThread3_1(service); MyThread3_2 t2 = new MyThread3_2(service); t1.setName("A"); t2.setName("B"); t1.start(); t2.start(); } }
获得读锁 B 时间 1575728981271
获得读锁 A 时间 1575728981271
(二)ReentrantReadWriteLock类 使用,写写互斥。
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Service14 { private ReentrantReadWriteLock lock =new ReentrantReadWriteLock(); public void write(){ try { lock.writeLock().lock(); System.out.println("获得读锁 "+Thread.currentThread().getName()+ " 时间 "+ System.currentTimeMillis()); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.writeLock().unlock(); } } }
获得读锁 A 时间 1575731808939 获得读锁 B 时间 1575731813939
(三)ReentrantReadWriteLock类 使用,读写互斥。
package com.it.po.thread11.thread11_1; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Service14 { private ReentrantReadWriteLock lock =new ReentrantReadWriteLock(); public void write(){ try { lock.writeLock().lock(); System.out.println("获得读锁 "+Thread.currentThread().getName()+ " 时间 "+ System.currentTimeMillis()); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.writeLock().unlock(); } } public void read(){ try { lock.readLock().lock(); System.out.println("获得读锁 "+Thread.currentThread().getName()+ " 时间 "+ System.currentTimeMillis()); Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.readLock().unlock(); } } }

package com.it.po.thread11.thread11_1; public class Run14 { public static void main(String[] args) throws InterruptedException { Service14 service= new Service14(); MyThread3_1 t1 = new MyThread3_1(service); MyThread3_2 t2 = new MyThread3_2(service); t1.setName("A"); t2.setName("B"); t1.start(); Thread.sleep(200); t2.start(); } }
获得读锁 A 时间 1575732030460 获得读锁 B 时间 1575732035460
(四)ReentrantReadWriteLock类 使用,写读互斥。
package com.it.po.thread11.thread11_1; public class Run14 { public static void main(String[] args) throws InterruptedException { Service14 service= new Service14(); MyThread3_1 t1 = new MyThread3_1(service); MyThread3_2 t2 = new MyThread3_2(service); t1.setName("A"); t2.setName("B"); t2.start(); Thread.sleep(200); t1.start(); } }
获得读锁 B 时间 1575732258069
获得读锁 A 时间 1575732263070
浙公网安备 33010602011771号