ccse(CountDownLatch,CycliBarrier,Semaplore,Exchanger)
关于等待状态的线程调用interrupt方法报异常:InterruptedException
当线程被阻塞,比如wait,join,sleep等,在调用interrupt方法,没有占用cpu运行的线程是不可能给自己的中断状态置位的,这就产生了InterruptedException异常.
一.闭锁CountDownLatch(允许一个或多个线程等待其它线程完成操作)
代码实例:
package com.thread.ccse; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; /**
* Created by IntelliJ IDEA.
* User: 周强
* Description:
* Date: 2017/8/9
* Time: 21:04
*/
public class CountDownLatchTest {
public static CountDownLatch c = new CountDownLatch(4);
public static void main(String [] args) throws InterruptedException {
Thread t =new Thread(new Runnable() {
@Override
public void run() {
System.out.println(c.getCount()); //第1
c.countDown();
System.out.println(c.getCount());//第2
c.countDown();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(c.getCount());//第3
c.countDown();
System.out.println(c.getCount());//第4
}
});
t.start();
c.await(2, TimeUnit.SECONDS);
c.countDown();
System.out.println(c.getCount( ));//第5
}
}
输出结果如下:
Connected to the target VM, address: '127.0.0.1:55816', transport: 'socket'
4 第1
3 第2
1 第5
Disconnected from the target VM, address: '127.0.0.1:55816', transport: 'socket'
1 第3
0 第4 Process finished with exit code 0
由于线程t沉睡时间大于CountDownLatch c的等待时间,所以线程t在主线证执行完毕后才结束的.
二:栅栏CyclicBarrier(指定线程数,必须在该线程数内的线程全部到达同步点,才继续往下执行)
示例代码:
package com.thread.ccse; import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; /**
* Created by IntelliJ IDEA.
* User: 周强
* Description:
* Date: 2017/8/9
* Time: 21:30
*/
public class CyclicBarrierTest { static Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("3");
}
}); static Thread thread = null;
public static CyclicBarrier c = new CyclicBarrier(2,t);
static {
thread = new Thread(new Runnable() {
@Override
public void run() {
try {
c.await();
System.out.println("1");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
});
} public static void main(String [] args){ thread.start();
try {
c.await();
System.out.println("2");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
} }
执行结果:
Disconnected from the target VM, address: '127.0.0.1:56157', transport: 'socket'
3
2
1//其中,3 肯定是最先输出的,1 和 2 的输出顺序是不一定的 Process finished with exit code 0
CountDownLatch和CyclicBarrier的区别:
CountDownLatch计数器只能使用一次,而CyclicBarrier的计数器可以使用多次,因为CyclicBarrier可以使用reset方法重置计数器;
CyclicBarrier还提供其它方法,如getNumberWating方法可以获得CyclicBarrier阻塞的线程数,isBroken方法可以用来了解阻塞的线程是否被中断。
三:有界容器Semaphore(构造固定长度的资源池)
代码示例:
package com.thread; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore; /**
* Created by 周强 on 2017/8/10.
*/
public class SemaphoreTest {
public static Semaphore s = new Semaphore(1);
public static volatile int i =1;
public static List<String> list = new ArrayList(); public static void main(String [] args) throws InterruptedException {
Thread a = new Thread(new ta());
Thread b = new Thread(new tb()); s.acquire(); //消费唯一许可;
a.start();
b.start(); } static class ta implements Runnable{
@Override
public void run() {
System.out.println("开始");
try {
s.acquire(); //唯一许可已被消费了,此处被阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
list.add(String.valueOf(i));
i++;
System.out.println("开始---end"); }
}
static class tb implements Runnable{
@Override
public void run() {
System.out.println("acquire");
list.remove(String.valueOf(i));
System.out.println(list.toString());
s.release();、//释放许可
}
}
}
执行结果:
Disconnected from the target VM, address: '127.0.0.1:65218', transport: 'socket'
开始
acquire
[]
1
开始---end Process finished with exit code 0
四.(线程同步)Exchanger()
代码示例:
package com.thread; import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* Created by 周强 on 2017/8/10.
*/
public class ExchangerTest {
public static Exchanger<String> exgr = new Exchanger<String>();
public static ExecutorService threadPool = Executors.newFixedThreadPool(2); public static void main(String [] args){
threadPool.execute(new Runnable() { //线程A
@Override
public void run() {
String a = "a"; try {
exgr.exchange(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("a ="+a );
}
});
threadPool.execute(new Runnable() { //线程B
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String b = "b";
String a = null;
try {
a = exgr.exchange("b");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("a ="+a +" "+"b ="+b);
}
});
threadPool.shutdown();
}
}
执行结果:
结果一:
Connected to the target VM, address: '127.0.0.1:49408', transport: 'socket'
a =a b =b
a =a
Disconnected from the target VM, address: '127.0.0.1:49408', transport: 'socket'
结果二:
Connected to the target VM, address: '127.0.0.1:49524', transport: 'socket'
a =a
a =a b =b
Disconnected from the target VM, address: '127.0.0.1:49524', transport: 'socket'
结论:虽然线程B沉睡了1秒,但由于线程A和B都在exgr.exchange处阻塞了,互相等待,且阻塞后的只剩下了打印的操作,所以,打印操作的先后顺序并能确定.
Exchanger(交换者)是一个用于线程间协作的工具类。Exchanger用于进行线程间的数据交换。它提供一个同步点,在这个同步点两个线程可以交换彼此的数据。这两个线程通过exchange方法交换数据, 如果第一个线程先执行exchange方法,它会一直等待第二个线程也执行exchange,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。
以上为本次学习 闭锁(CountDownLatch),栅栏(CyclicBarrier),有界容器(Semaphore)和线程同步工具类(Exchange)四个多线程相关工具类的代码笔记,工作中没有使用过,权且学习积累,以备后用。
//线程A
ccse(CountDownLatch,CycliBarrier,Semaplore,Exchanger)的更多相关文章
- java 5线程中 Semaphore信号灯,CyclicBarrier类,CountDownLatch计数器以及Exchanger类使用
先来讲解一下Semaphore信号灯的作用: 可以维护当前访问自身的线程个数,并提供了同步机制, 使用semaphore可以控制同时访问资源的线程个数 例如,实现一个文件允许的并发访问数. 请看下面 ...
- Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger
在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...
- 并发工具类的使用 CountDownLatch,CyclicBarrier,Semaphore,Exchanger
1.CountDownLatch 允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助. A CountDownLatch用给定的计数初始化. await方法阻塞,直到由于countDo ...
- Java并发II
Java并发 J.U.C图 一.线程的安全性 当多个线程访问某个类的时候,不管运行环境采用何种方式调度或者这些线程如何交替执行,并且在主调代码中不需要任何额外的同步或者协同,这个类都可以表现出正确的行 ...
- 《大型网站系统与Java中间件实践》读书笔记
分布式系统的基础知识 阿姆达尔定律 多线程交互模式 互不通信,没有交集,各自执行各自的任务和逻辑 基于共享容器(如队列)协同的多线程模式->生产者-消费者->队列 通过事件协同的多线程模式 ...
- java effective 读书笔记
java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 si ...
- java互斥方法
synchronized, lock/unlock, volatile类型变量, atom类, 同步集合, 新类库中的构件: CountDownLatch\CyclicBarric\Semaph ...
- Java 可中断线程
PART.1 无法中断的线程 一个无法中断的线程的例子. public class UninterruptableThread { @SuppressWarnings("deprecatio ...
- JAVA 并发编程关键点
上下文切换 死锁 volatile synchronized 原子操作 happens-before as-if serial 锁的内存 final 线程:daemon start suspend r ...
随机推荐
- js 点击复制代码 window.clipboardData.setData
var v = document.getElementById("forcopy").value; window.clipboardData.setData('text',v); ...
- 文本分类实战(五)—— Bi-LSTM + Attention模型
1 大纲概述 文本分类这个系列将会有十篇左右,包括基于word2vec预训练的文本分类,与及基于最新的预训练模型(ELMo,BERT等)的文本分类.总共有以下系列: word2vec预训练词向量 te ...
- 24 python初学(异常)
try, except, else, finally执行顺序:1. 先执行 try 里面的代码块,如果发生异常就会去捕获. 2. 没有错误就会执行 else 里面的信息. 3. 无论怎样都会执行 fi ...
- jmeter(二十五)linux环境运行jmeter并生成报告
jmeter是一个java开发的利用多线程原理来模拟并发进行性能测试的工具,一般来说,GUI模式只用于创建脚本以及用来debug,执行测试时建议使用非GUI模式运行. 这篇博客,介绍下在linux环境 ...
- ELK原理与简介
为什么用到ELK: 一般我们需要进行日志分析场景:直接在日志文件中 grep.awk 就可以获得自己想要的信息.但在规模较大的场景中,此方法效率低下,面临问题包括日志量太大如何归档.文本搜索太慢怎么办 ...
- 怎么在Vue的某个组件中根据组件tag标签名获取到对应的VueComponent实例呢
1.以前玩omi框架的时候,有Omi.get方法来获取实例, ...好久没玩了,忘了.反正很喜欢该方法.2.如今想在vue里面怎么能够快速获取到对应组件标签名的的实例呢?3.文档也看过,似乎脑海中没啥 ...
- 模型加速[tensorflow&tensorrt]
在tensorflow1.8之后的版本中,tensorflow.contrib部分都有tensorrt的组件,该组件存在的意义在于,你可以读取pb文件,并调用tensorrt的方法进行subgraph ...
- (haut oj 1261 ) 地狱飞龙 利用不定积分求值
题目链接:http://218.28.220.249:50015/JudgeOnline/problem.php?id=1261 题目描述 最近clover迷上了皇室战争,他抽到了一种地狱飞龙,很开心 ...
- 如何给框架添加API接口日志
前言 用的公司的框架,是MVC框架,看了下里面的日志基类,是操作日志,对增删改进行记录, 夸张的是一张业务的数据表 需要一张专门的日志表进行记录, 就是说你写个更新,添加的方法都必须写一遍操作日志,代 ...
- react 报错的堆栈处理
react报错 Warning: You cannot PUSH the same path using hash history 在Link上使用replace 原文地址https://reactt ...