标签:display ret mic jvm efi 连接 this tin cpu
以上是核心的关于CountDownLatch、ReentrantLock的分析。由于博主研究程度有限,想更深层次研究,请参考:Java并发AQS详解
/** * CountDownLatch相当于指令枪或者门闩,所有线程都awit()阻塞在起跑线,只有countDown到state为0,其他线程才能往下运行。 * @author qiuyongAaron */ public class CountDownLatchDemo { private static final int PLAYER_NUM=5; public static void main(String[] args) { CountDownLatch start=new CountDownLatch(1); CountDownLatch end =new CountDownLatch(PLAYER_NUM); Player [] players=new Player[PLAYER_NUM]; for(int i=0;i<PLAYER_NUM;i++) players[i]=new Player(start, end, i); //指定线程个数的线程池! ExecutorService exe=Executors.newFixedThreadPool(PLAYER_NUM); for(Player player:players) exe.execute(player); System.out.println("比赛开始!"); //比赛开始! start.countDown(); try { end.await(); } catch (InterruptedException e) { e.printStackTrace(); }finally{ System.out.println("比赛结束!"); exe.shutdown(); } } } class Player implements Runnable{ private CountDownLatch start; private CountDownLatch end; private int id; Random random=new Random(); public Player(CountDownLatch start,CountDownLatch end,int id) { this.start=start; this.end=end; this.id=id; } @Override public void run() { try { //等待比赛开始。 start.await(); TimeUnit.SECONDS.sleep(random.nextInt(10)); System.out.println("Player-"+id+":arrived"); } catch (InterruptedException e) { e.printStackTrace(); }finally{ //选手-id到达终点,end计数为0结束比赛! end.countDown(); } } } //运行结果: 比赛开始! Player-3:arrived Player-4:arrived Player-0:arrived Player-1:arrived Player-2:arrived 比赛结束!
/** * 示例一:同步锁的使用 * reentrantlock用于替代synchronized * 本例中由于m1锁定this,只有m1执行完毕的时候,m2才能执行 * @author qiuyongAaron */ public class ReentrantLockOne { public synchronized void m1(){ for(int i=0;i<10;i++){ try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(i); } } public synchronized void m2(){ System.out.println("hello m2!"); } public static void main(String[] args) { ReentrantLockOne lock=new ReentrantLockOne(); new Thread(()->lock.m1(),"t1").start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->lock.m2(),"t2").start(); } }
2.2 ReentrantLock实现线程同步-与synchronized作用一致!
/** * 示例二:等价于同步锁 * 使用reentrantlock可以完成同样的功能 * 需要注意的是,必须要必须要必须要手动释放锁(重要的事情说三遍) * 使用syn锁定的话如果遇到异常,jvm会自动释放锁,但是lock必须手动释放锁,因此经常在finally中进行锁的释放 * @author qiuyongAaron */ public class ReentrantLockTwo { ReentrantLock lock =new ReentrantLock(); public void m1(){ try { lock.lock(); for(int i=0;i<10;i++){ TimeUnit.SECONDS.sleep(1); System.out.println(i); } } catch (InterruptedException e) { e.printStackTrace(); }finally{ lock.unlock(); } } public synchronized void m2(){ lock.lock(); System.out.println("hello m2!"); lock.unlock(); } public static void main(String[] args) { ReentrantLockTwo lock=new ReentrantLockTwo(); new Thread(()->lock.m1(),"t1").start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->lock.m2(),"t2").start(); } }
/** * 示例三:tryLock * 使用reentrantlock可以进行“尝试锁定”tryLock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续等待 * @author qiuyongAaron */ public class ReentrantLockThree { ReentrantLock lock=new ReentrantLock(); public void m1(){ try { lock.lock(); for(int i=0;i<10;i++){ TimeUnit.SECONDS.sleep(1); System.out.println(i); } } catch (Exception e) { e.printStackTrace(); }finally{ lock.unlock(); } } boolean locked=false; public void m2(){ try { lock.tryLock(5,TimeUnit.SECONDS); System.out.println("m2:"+locked); } catch (Exception e) { e.printStackTrace(); }finally{ if(locked) lock.unlock(); } } public static void main(String[] args) { ReentrantLockThree lock=new ReentrantLockThree(); new Thread(()->lock.m1(),"t1").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->lock.m2(),"t2").start(); } }
2.4 指定公平锁或者抢占式锁
/** * ReentrantLock还可以指定为公平锁 * @author qiuyongAaron */ public class ReentrantLockFive extends Thread{ //默认false:为非公平锁 true:公平锁 ReentrantLock lock=new ReentrantLock(); @Override public void run() { for(int i=0;i<100;i++){ lock.lock(); try { TimeUnit.SECONDS.sleep(1); System.out.println(Thread.currentThread().getName()+"获得锁"+"-"+i); } catch (InterruptedException e) { e.printStackTrace(); }finally{ lock.unlock(); } } } public static void main(String[] args) { ReentrantLockFive lock=new ReentrantLockFive(); new Thread(lock,"t1").start(); new Thread(lock,"t2").start(); } } 运行结果: //非公平锁 t2获得锁-0 t2获得锁-1 t1获得锁-0 t1获得锁-1 t1获得锁-2 t2获得锁-2 //公平锁 t1获得锁-0 t2获得锁-0 t1获得锁-1 t2获得锁-1 t1获得锁-2 t2获得锁-2
/** * 模拟生产者消费者模式-线程之间通信 synchronized-notifyAll/wait * @author qiuyongAaron */ public class MyContainerOne { LinkedList<Integer> list=new LinkedList<Integer>(); static final int MAX=10; int count=0; //生产者线程 public synchronized void put(int i){ while(list.size()==MAX){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } list.add(i); ++count; this.notifyAll();//通知消费者来消费 } //消费者线程 public synchronized int get(){ while(list.size()==0){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } int num=list.removeFirst(); count--; this.notifyAll();//通知生产者生产 return num; } public static void main(String[] args) { MyContainerOne container=new MyContainerOne(); //制造10个消费者 for(int i=0;i<10;i++){ new Thread(()->{ for(int j=0;j<5;j++) System.out.println(container.get()); }, "c"+i).start(); } try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } //制造2个生产者 for(int i=0;i<2;i++){ new Thread(()->{ for(int j=0;j<25;j++) container.put(j); }, "p"+i).start(); } } }
/** * 模拟生产者消费者模式-reentrantLock-awit/signAll * @author qiuyongAaron */ public class MyContainerTwo { LinkedList<Integer> list=new LinkedList<Integer>(); static final int MAX=10; int count=0; ReentrantLock lock=new ReentrantLock(); Condition producer=lock.newCondition(); Condition consumer=lock.newCondition(); //生产者线程 public void put(int i){ try { lock.lock(); while(list.size()==MAX){ producer.await(); } list.add(i); ++count; consumer.signalAll();//通知消费者来消费 } catch (InterruptedException e){ e.printStackTrace(); }finally{ lock.unlock(); } } //消费者线程 public int get(){ try{ lock.lock(); while(list.size()==0){ consumer.await(); } int num=list.removeFirst(); count--; producer.signalAll();//通知生产者生产 return num; }catch(Exception e){ e.printStackTrace(); }finally{ lock.unlock(); } return 0; } public static void main(String[] args) { MyContainerTwo container=new MyContainerTwo(); //制造10个消费者 for(int i=0;i<10;i++){ new Thread(()->{ for(int j=0;j<5;j++) System.out.println(container.get()); }, "c"+i).start(); } try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } //制造2个生产者 for(int i=0;i<2;i++){ new Thread(()->{ for(int j=0;j<25;j++) container.put(j); }, "p"+i).start(); } } }
作者:邱勇Aaron
出处:http://www.cnblogs.com/qiuyong/
您的支持是对博主深入思考总结的最大鼓励。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,尊重作者的劳动成果。
参考:马士兵并发编程、并发编程实践
AQS详解:http://www.cnblogs.com/waterystone/p/4920797.html
并发编程(三):从AQS到CountDownLatch与ReentrantLock
标签:display ret mic jvm efi 连接 this tin cpu
原文地址:http://www.cnblogs.com/qiuyong/p/7102779.html