java 多线程,
分享于 点击 4196 次 点评:68
java 多线程,
1 信号量 Semaphore
1 信号量 可以控制某个资源被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而
release() 释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数
Semaphore实现的功能就类似厕所有5个坑,假如有10个人要上厕所,那么同时只能有多少个人去上厕所呢?同时只能有5个人能够占用,当5个人中 的任何一个人让开后,其中等待的另外5个人中又有一个人可以占用了。另外等待的5个人中可以是随机获得优先机会,也可以是按照先来后到的顺序获得机会,这取决于构造Semaphore对象时传入的参数选项。单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是由一个线程获得了“锁”,再由另一个线程释放“锁”,这可应用于死锁恢复的一些场合。
public class MyTest {
public static void main(String[] args) {
ExecutorService poll = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(5);
for (int i = 0; i < 10; i++){
Runnable run = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
semaphore.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
semaphore.release();
}
};
poll.execute(run);
}
}
}
2 阻塞队列
java.util.concurrent.BlockingQueue 接口表示阻塞队列,阻塞队列的概念是,对一定长度的队列,如果队列满了,添加新元素的操作会被阻塞等待,直到有空位为止,当
队列为空时,请求队列元素的操作会被阻塞,直到有新元素为止。
阻塞队列为多线程的排队等候模型提供便利
public class MyTest {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Integer> q = new ArrayBlockingQueue<>(4);
for (int i = 0; i < 8; i++){
q.put(i);
System.out.println(i);
}
System.out.println("over");
}
}
3 障碍器
原因 java.util.concurrent.CyclicBarrier; 比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择障碍器了
public class Test {
public static void main(String[] args) {
//创建障碍器,并设置MainTask为所有定数量的线程都达到障碍点时候所要执行的任务(Runnable)
CyclicBarrier cb = new CyclicBarrier(7, new MainTask());
new SubTask("A", cb).start();
new SubTask("B", cb).start();
new SubTask("C", cb).start();
new SubTask("D", cb).start();
new SubTask("E", cb).start();
new SubTask("F", cb).start();
new SubTask("G", cb).start();
}
}
/**
* 主任务
*/
class MainTask implements Runnable {
public void run() {
System.out.println(">>>>主任务执行了!<<<<");
}
}
/**
* 子任务
*/
class SubTask extends Thread {
private String name;
private CyclicBarrier cb;
SubTask(String name, CyclicBarrier cb) {
this.name = name;
this.cb = cb;
}
public void run() {
System.out.println("[子任务" + name + "]开始执行了!");
for (int i = 0; i < 999999; i++) ; //模拟耗时的任务
System.out.println("[子任务" + name + "]开始执行完成了,并通知障碍器已经完成!");
try {
//通知障碍器已经完成
cb.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
相关文章
- 暂无相关文章
用户点评