多线程之线程等待与信号量
来源:互联网 发布:tensorflow anaconda 编辑:程序博客网 时间:2024/06/07 21:20
笔记整理自:
http://www.cnblogs.com/dolphin0520/p/3920397.html
CountDownLatch用法(无法重复使用)
CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。
CountDownLatch类只提供了一个构造器:
//参数count为计数值 public CountDownLatch(int count) {};
下面这3个方法是CountDownLatch类中最重要的方法:
//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
//将count值减1
public void countDown() { };
运用实例:
public class Test { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(2); new Thread(){ public void run() { try { System.out.println("子线程"+Thread.currentThread().getName()+"正在执行"); Thread.sleep(3000); System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕"); //线程执行完,latch减1 latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); new Thread(){ public void run() { try { System.out.println("子线程"+Thread.currentThread().getName()+"正在执行"); Thread.sleep(3000); System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕"); latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); try { System.out.println("等待2个子线程执行完毕...");//主线程被等待,知道latch的count为0才继续执行 latch.await(); System.out.println("2个子线程已经执行完毕"); System.out.println("继续执行主线程"); } catch (InterruptedException e) { e.printStackTrace(); } }}
CyclicBarrier用法(可以重复使用)
字面意思回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。我们暂且把这个状态就叫做barrier,当调用await()方法之后,线程就处于barrier了。
CyclicBarrier类位于java.util.concurrent包下,CyclicBarrier提供2个构造器:
//parties:指让多少个线程等待至barrier状态;
//barrierAction:当这些线程都达到barrier状态时会执行的内容。
public CyclicBarrier(int parties, Runnable barrierAction) {}
public CyclicBarrier(int parties) {}
然后CyclicBarrier中最重要的方法就是await方法:
//用来挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务
public int await() throws InterruptedException, BrokenBarrierException { };
//让线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { };
运用实例:
假若有若干个线程都要进行写数据操作,并且只有所有线程都完成写数据操作之后,这些线程才能继续做后面的事情,此时就可以利用CyclicBarrier了。
public class Test { public static void main(String[] args) { int N = 4; CyclicBarrier barrier = new CyclicBarrier(N); for(int i=0;i<N;i++) new Writer(barrier).start(); } static class Writer extends Thread{ private CyclicBarrier cyclicBarrier; public Writer(CyclicBarrier cyclicBarrier) { this.cyclicBarrier = cyclicBarrier; } @Override public void run() { System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据..."); try { Thread.sleep(5000); //以睡眠来模拟写入数据操作 System.out.println(Thread.currentThread().getName()+"写完毕,等其他线程"); cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); }catch(BrokenBarrierException e){ e.printStackTrace(); } System.out.println("所有线程写入完毕,继续处理其他任务..."); } }}
Semaphore用法
Semaphore翻译成字面意思为 信号量,Semaphore可以控同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
Semaphore类位于java.util.concurrent包下,它提供了2个构造器:
//参数permits表示许可数目,即同时可以允许多少线程进行访问
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
//这个多了一个参数fair表示是否是公平的,即等待时间越久的越先获取许可
public Semaphore(int permits, boolean fair) {
sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
}
Semaphore类中比较重要的几个方法:
//获取一个许可,若无许可能够获得,则会一直等待,直到获得许可
public void acquire() throws InterruptedException { }
//获取permits个许可
public void acquire(int permits) throws InterruptedException { }
//释放许可。注意,在释放许可之前,必须先获获得许可
public void release() { }
//释放permits个许可
public void release(int permits) { }
上面这4个方法都会被阻塞,如果想立即得到执行结果,可以使用下面几个方法:
//尝试获取一个许可,若获取成功,则立即返回true,若获取失败,则立即返回false
public boolean tryAcquire() { };
//尝试获取一个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回false
public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException { };
//尝试获取permits个许可,若获取成功,则立即返回true,若获取失败,则立即返回false
public boolean tryAcquire(int permits) { };
//尝试获取permits个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回false
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException { };
运用实例:
假若一个工厂有5台机器,但是有8个工人,一台机器同时只能被一个工人使用,只有使用完了,其他工人才能继续使用。那么我们就可以通过Semaphore来实现。
public class Test { public static void main(String[] args) { int N = 8; //工人数 Semaphore semaphore = new Semaphore(5); //机器数目 for(int i=0;i<N;i++) new Worker(i,semaphore).start(); } static class Worker extends Thread{ private int num; private Semaphore semaphore; public Worker(int num,Semaphore semaphore){ this.num = num; this.semaphore = semaphore; } @Override public void run() { try { semaphore.acquire(); System.out.println("工人"+this.num+"占用一个机器在生产..."); Thread.sleep(2000); System.out.println("工人"+this.num+"释放出机器"); semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } } }}
- 多线程之线程等待与信号量
- Win32多线程之线程等待
- Java多线程基础--05之 线程等待与唤醒
- Java多线程--线程等待与唤醒
- java基本教程之java线程等待与java唤醒线程 java多线程教程
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- java多线程之 生产者和消费者 线程间通信 等待与唤醒机制
- Java多线程系列--“基础篇”05之 线程等待与唤醒 (r)
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- Java多线程系列--“基础篇”05之 线程等待与唤醒
- 利用信号量使线程进入等待状态
- 多线程开发学习笔记之线程同步——信号量
- 多线程之线程同步中的信号量AutoResetEvent和ManualResetEvent
- linux多线程学习笔记三---线程同步之信号量
- 多线程之八 经典线程同步 信号量Semaphore
- 从数据库角度描述CPU、内存、硬盘三者关系
- 题目1056:最大公约数
- GCD group 用法 and 项目实践
- pgsql用户自定义表结构信息获取
- 架构设计:负载均衡层设计方案(1)——负载场景和解决方式
- 多线程之线程等待与信号量
- 线程死锁
- RelativeLayout常用属性介绍
- 命令模式
- php模板原理
- 菜鸡与React互啄激烈过程
- [Torch] 2. torch
- 网络编程(一)--基本概念
- replica character liquid crystal display control