Java 并发编程 四 协作
来源:互联网 发布:qq视频录制软件 编辑:程序博客网 时间:2024/05/22 17:45
## 1、ReadWriteLock读写锁
概念很好理解,下面是代码:
package com.test.thread3;import java.util.Random;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteReentrantLockTest { private static Lock lock = new ReentrantLock(); private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private static Lock readLock = readWriteLock.readLock(); private static Lock WriteLock = readWriteLock.writeLock(); private int value; public Object handleRead(Lock lock) throws InterruptedException { try { lock.lock(); Thread.sleep(1000); return value; } finally { lock.unlock(); } } public void handleWrite(Lock lock, int index) throws InterruptedException { try { lock.lock(); Thread.sleep(1000); value = index; } finally { lock.unlock(); } } public static void main(String args[]) { final ReadWriteReentrantLockTest demo = new ReadWriteReentrantLockTest(); Runnable read = new Runnable() { public void run() { try { //demo.handleRead(lock); int i= (Integer) demo.handleRead(readLock); System.out.println("read:"+i); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; Runnable write = new Runnable() { public void run() { try { int i = new Random().nextInt(); System.out.println(Thread.currentThread().getId()+" i "+i); demo.handleWrite(WriteLock, i); // demo.handleWrite(lock, new Random().nextInt()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; for(int i=0;i<18;i++){ new Thread(read).start(); } for(int i=18;i<20;i++){ new Thread(write).start(); } try { Thread.sleep(3000); System.out.println(demo.value); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
可以观察到使用普通的ReetrantLock 和 ReentrantReadWriteLock执行时间的区别。
##2、倒计时器 CountDownLatch
CountDownLatch 是一个非常使用的多线程控制工具类。CountDown 在英文中意为倒计数,Latch是门闩的意思。 门闩的含义是:把门锁起来,不让里面的线跑出来。因此这个歌工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束,再开始执行。
public class CountDownLatchDemo implements Runnable { static final CountDownLatch end = new CountDownLatch(10); static final CountDownLatchDemo demo = new CountDownLatchDemo(); public void run() { try { Thread.sleep(new Random().nextInt(10) * 1000); System.out.println("check complete"); end.countDown(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String args[]) throws InterruptedException { ExecutorService exec = Executors.newFixedThreadPool(10); for (int i = 0; i < 10; i++) { exec.submit(demo); } end.await(); System.out.println("Fire"); exec.shutdown(); }}
##3、循环栅栏 CyclicBarrier
CyclicBarrier是另外一种多线程并发控制的实用工具。和CountDownLatch非常类似,它可以实现线程间的计数等待,但它的功能比CountDownLatch更加复杂强大。它有循环的功能,也就是这个计数器可以反复使用。
public class Soldier implements Runnable { private String soldier; private final CyclicBarrier cyclic; Soldier(CyclicBarrier cyclic, String soldierName) { this.cyclic = cyclic; this.soldier = soldierName; } public void run() { try { cyclic.await(); // 等待前面的任务执行完成。 再一起执行后面的任务。 doWork(); cyclic.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { } } void doWork(){ try{ Thread.sleep(Math.abs(new Random().nextInt()%10000)); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println(soldier+": 任务完成。"); }}public class BarrierRun implements Runnable { boolean flag; int N; public BarrierRun(boolean flag, int N){ this.flag = flag; this.N=N; } public void run() { if(flag){ System.out.println("司令:[士兵 "+N+"个, 任务完成!"); }else{ System.out.println("司令:[士兵 "+N+"个, 集合完毕!"); flag = true; } }}public class CyclicBarrierDemo { public static void main(String args[]){ final int N=10; Thread[] allSoldier = new Thread[N]; boolean flag = false; CyclicBarrier cyclic = new CyclicBarrier(N,new BarrierRun(flag,N)); System.out.println("集合队伍"); for(int i=0;i<11;++i){ System.out.println("士兵 "+i+"报道!"); allSoldier[i] = new Thread(new Soldier(cyclic,"士兵"+i)); allSoldier[i].start(); } }}
##4、线程阻塞工具栏 LockSupport
LockSupport 是一个非常方便使用的线程阻塞工具,它可以在线程内任意位置让线程阻塞。和Thead。suspend 相比,他弥补了由于resume在前发生,导致线程无法继续执行的情况。和Object.wait 相比,他不需要先获得某个对象的锁,也不会抛出InterruptedException异常。
LockSupport使用类似信号量的机制。它为每个线程准备了一个许可,如果许可可用,那么park函数立即返回,并且消费这个许可,如果许可不可用,就会阻塞,而unpark 则使得一个许可变为可用(但是和信号量不同的是,许可不能累加,你不可能拥有超过一个许可,它永远只有一个。)
public class ChangeObjectThread extends Thread { public static Object u = new Object(); public ChangeObjectThread(String name) { super.setName(name); } public void run() { synchronized (u) { System.out.println("in " + getName()); LockSupport.park(); LockSupport.park(); } }}public class LockSupportDemo { static ChangeObjectThread t1 = new ChangeObjectThread("t1"); static ChangeObjectThread t2 = new ChangeObjectThread("t2"); public static void main(String[] args) throws InterruptedException { t1.start(); LockSupport.unpark(t1); Thread.sleep(1000); LockSupport.unpark(t1);// 这两个许可如果放在一块,只会产生一个许可,因为线程中有两个park,所以会一直阻塞,因此需要使用sleep分开。 t2.start(); //LockSupport.park(t1); LockSupport.unpark(t2); Thread.sleep(1000); LockSupport.unpark(t2); t1.join(); t2.join(); }}
- Java 并发编程 四 协作
- java编程思想笔记-并发之线程协作(四)
- Java并发总结(四):线程的协作
- java多线程并发(四)(线程协作)
- JAVA并发编程6_线程协作/生产者-消费者
- Java并发编程:线程间协作的两种方式
- Java并发编程:Condition实现线程间协作
- Java并发编程实战笔记(5)- 线程协作
- 10 Java并发编程3-线程间协作总结
- java编程思想笔记-并发之线程协作(一)
- java编程思想笔记-并发之线程协作(二)
- java编程思想笔记-并发之线程协作(三)
- JAVA并发编程笔记四
- java并发编程之四
- Java并发编程(四)--Semaphore
- Java 并发编程(四)并发容器
- 并发编程(三)-线程协作
- Java线程:并发协作-死锁
- MySQL之——优化篇(重要)
- [Sklearn应用3] Preprocessing data (三)编码分类特征 Encoding categorical features
- u-boot移植(三)使支持norflash
- MBR 和 GPT分区的区别
- java-方法的重写以及方法重写和方法重载的区别
- Java 并发编程 四 协作
- json和jsonp
- 数组更新检测
- 草根学Python(四) Dict 和 Set
- 关于苹果手机显示像素处理
- 剑指offer——两个链表的第一个公共结点(给出的方法,都是针对有且只有一个公共节点的方法)
- 中国潜文化·天下无谋文丛
- c#多个窗体之间传值
- 单链表冒泡排序与数组冒泡排序