线程的常用知识(包括 Thread/Executor/Lock-free/阻塞/并发/锁等)
本次内容列表:
1.使用线程的经验:设置名称、响应中断、使用ThreadLocal
2.Executor:ExecutorService和Future
3.阻塞队列:put和take、offer和poll、drainTo
4.线程间的协调手段:lock、condition、wait、notify、notifyAll
5.Lock-free:atomic、concurrentMap.putlfAbsent、CopyOnWriteArrayList
6.关于锁使用的经验介绍
7.并发流程控制手段:CountDownlatch、Barrier
8.定时器:ScheduledExecutorService、大规模定时器TimeWheel
9.并发三大定律:Amdahl、Gustafson、Sun-Ni
1.线程的经验:无论何种方式,启动一个线程,就要给它一个名字。这对排错诊断系统监控有帮助。否则诊断问题时,无法直观知道某个线程的用途
设置名称:以下为常用的几种命名方式:
1 //命名方式一:
2 Thread thread = new Thread("thread name one") {
3 public void run() {
4 //do xxx
5 }
6 };
1 //命名方式二:
2 Thread thread = new Thread() {
3 public void run() {
4 //do xxx
5 }
6 };
7 thread.setName("thread name two");
8 thread.start();
1 //命名方式三:
2 public class MyThread extends Thread{
4 public MyThread() {
5 super("thread name three");
6 }
7 public void run() {
8 //do xxx
9 }
10 }
11 MyThread thread = new MyThread();
12 thread.start();
1 //命名方式四:
2 Thread thread = new Thread(task, "thread name four");
3 thread.start();
响应线程中断:thread.interrupt(); 程序应该对线程中断作出恰当的响应
1 //中断响应方式一:
2 Thread thread = new Thread("interrupt test") {
3 public void run() {
4 for(;;) {
5 try {
6 doXXX();
7 } catch(InterruptedException e) {
8 break;
9 } catch(Exception e) {
10 //handle Exception
11 }
12 }
13 }
14 };
15 thread.start();
1 //中断响应方式二:
2 Thread thread = new Thread("interrupt test") {
3 public void run() {
4 for(;;) {
5 if(Thread.interrupted()) {
6 break;
7 }
8 }
9 }
10 };
11 thread.start();
1 //中断响应方式三:
2 public void foo() throws InterruptedException{
3 if(Thread.interrupted()) {
4 throw new InterruptedException();
5 }
6 }
ThreadLocal(局部线程变量):它的功能非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。使用ThreadLocal,一般都是声明在静态变量中,如果不断的创建ThreadLocal而且没有调用其remove方法,将会导致内存泄漏。如果是static的ThreadLocal,一般不需要调用remove。
2.Executor
为了方便并发执行任务,使用Executor用来专门执行任务的实现,任务的提交者不需要在创建管理线程,使用更方便,也减少了开销。
java.util.concurrent.Executors是Executor的工厂类,通过Executors可以创建你所需要的Executor。
任务的提交者和执行者之间的通讯手段
1 ExecutorService executor = Executors.newSingleThreadExecutor();
2 Callable<Object> task = new Callable<Object>() {
3 @Override
4 public Object call() throws Exception {
5 Object result = "";
6 return result;
7 }
8 };
9 public void subTask() {
10 Future<Object> future = executor.submit(task);
11 try {
12 future.get(); //等待至完成
13 } catch (InterruptedException e) {
14 e.printStackTrace();
15 } catch (ExecutionException e) {
16 e.printStackTrace();
17 }
18 }
Task Submitter
1 Future<Object> future = executor.submit(task);
2 //等待到任务被执行完毕返回结果
3 //如果任务执行出错,这里会抛ExecutionException
4 future.get();
5 //等待3秒,超时后会抛TimeoutException
6 future.get(3, TimeUnit.SECONDS);
Task Executor
1 Callable<Object> task = new Callable<Object>() {
2 @Override
3 public Object call() throws Exception {
4 Object result = ...;
5 return result;
6 }
7 };
Task Submitter 把任务提交给Executor执行,他们之间需要一种通讯手段,这种手段的具体实现,通常叫做Future。Future通常包括get(阻塞至任务完成),cancel, get(timeout)(等待一段时间)等等。Future也用于异步变同步的场景。
3.阻塞队列:阻塞队列,是一种常用的并发数据结构,常用域生产者-消费者模式。
有多种阻塞队列:
ArrayBlockingQueue(最常用)
LinkedBolckingQueue(不会满的)
SynchronousQueue(size为0)
PriorityBlockingQueue
阻塞中常用的方法有:


注:在使用BlockingQueue的时候,尽量不要使用从Queue继承下来的方法,否则就失去了Blocking的特性了。
例1:
1 final BlockingQueue<Object> blockingQ = new ArrayBlockingQueue<Object>(10);
2 Thread thread = new Thread("consumer thread") {
3 public void run() {
4 for(;;) {
5 try {
6 Object object = blockingQ.take(); //等到有数据才继续
7 handle(object); //处理
8 } catch (InterruptedException e) {
9 break;
10 } catch(Exception e) {
11 e.printStackTrace();
12 }
13 }
14 }
15 };
例2:
1 final BlockingQueue<Object> blockingQ = new ArrayBlockingQueue<Object>(10);
2 Thread thread = new Thread("consumer thread two") {
3 public void run() {
4 for(;;) {
5 try {
6 Object object = blockingQ.poll(1, TimeUnit.SECONDS); //防止死锁
7 if(object == null) {
8 //TODO
9 continue; //或者进行其他操作
10 }
11 } catch (InterruptedException e) {
12 break;
13 } catch (Exception e) {
14 e.printStackTrace();
15 }
16 }
17 }
18 };
线程的常用知识(包括 Thread/Executor/Lock-free/阻塞/并发/锁等)的更多相关文章
- Thread线程的基础知识及常见疑惑点
引言 相信各位道友在平时工作中已经很少直接用到Thread线程类了,现在大多是通过线程池或者一些多线程框架来操作线程任务,但我觉得还是有必要了解清楚Thread线程类中各种方法的含义,了解了底层才能更 ...
- JAVA常用知识总结(九)——线程
sleep和wait的区别? sleep()来自Thread类,和wait()来自Object类.调用sleep()方法的过程中,线程不会释放对象锁.而 调用 wait 方法线程会释放对象锁 slee ...
- {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器
Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...
- C#线程同步(1)- 临界区&Lock
文章原始出处 http://xxinside.blogbus.com/logs/46441956.html 预备知识:线程的相关概念和知识,有多线程编码的初步经验. 一个机会,索性把线程同步的问题在C ...
- 已看1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、多线程(并发编程)、I/O(NIO)、Socket、JDBC、XML、反射等。[泛型]\
1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架.多线程(并发编程).I/O(NIO).Socket.JDBC.XML.反射等.[泛型]\1* ...
- C#线程系列讲座(2):Thread类的应用
一.Thread类的基本用法 通过System.Threading.Thread类可以开始新的线程,并在线程堆栈中运行静态或实例方法.可以通过Thread类的的构造方法传递一个无参数,并且不返回值(返 ...
- Java程序员必备知识-多线程框架Executor详解
为什么引入Executor线程池框架 new Thread()的缺点 每次new Thread()耗费性能 调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞 ...
- c# 线程浅析(代理 、Invoke、Lock)
前言:本来想根据自己的经验总结一下c#线程相关的知识点, 写之前看了一些其他人的博客,发现自己也就掌握了不到三分之一....希望通过这次的博客将自己的知识点补充一下,写出更直白的博客和初学者分享. 这 ...
- [转]C#线程同步(1)- 临界区&Lock
第一印象,C#关于线程同步的东西好多,保持了C#一贯的大杂烩和四不象风格(Java/Delphi).临界区跟Java差不多只不过关键字用lock替代了synchronized,然后又用Moniter的 ...
随机推荐
- Docker单机网络上
前言 Docker系列文章: 此篇是Docker系列的第六篇,大家一定要按照我做的Demo都手敲一遍,印象会更加深刻的,加油! 为什么要学习Docker Docker基本概念 Docker镜像基本原理 ...
- Binding(五):多路绑定
Binding不止能绑定一个源,它还能绑定多个源,这就是我们这节要讲的多路绑定:MultiBinding. 使用多路绑定跟一般的绑定还是有区别的,首先它并不能很好的在标记扩展中使用,另外,使用多路绑定 ...
- Centos 8 上定时备份Gitlab ,脚本实现定时备份,备份恢复
定时备份 要求 为了能够备份和恢复,请确保你的系统上安装了Rsync yum install rsync -y 配置备份目标机器免密认证 执行ssh-keygen -t rsa 生成私钥和公钥 ssh ...
- actviti7撤回操作
@Override @Transactional(rollbackFor = Exception.class) public int callBack(String processId) { //通过 ...
- 【转载】CentOS-yum安装Docker环境
安装Docker环境 $ yum install docker -y 启动Docker $ systemctl start docker 设置自启动 $ systemctl enable docker ...
- ExtJs4学习(四):Extjs 中id与itemId的区别
为了方便表示或是指定一个组件的名称,我们通常会使用id或者itemId进行标识命名.(推荐尽量使用itemId,这样可以减少页面唯一标识而产生的冲突) id: id是作为整个页面的Compo ...
- [心得]安装MongoDB
1. 安装 (1) 其他默认 (2) 创建文件 在 E:\DevTools\MongoDB\Server\3.4 1 1 E:\DevTools\MongoDB\Server\3.4 下创建dat ...
- <c:out>标签不能正确输出value中的值
问题: 我打算在jsp中输出request中的值,它的key为username, <c:out value="${requestScope.username}"/> 但 ...
- esp32 Guru Meditation 错误解决方案(转)
Guru Meditation本节将对打印在 Guru Meditation Error: Core panic'ed后面括号中的致错原因进行逐一解释.IllegalInstruction此 CPU ...
- Java | this的本质 和 static的本质
this 在说this之前先说一下,对象创建的过程: 1.分配对象空间,并将对象成员变量初始化. 2.执行属性值的显式初始化. 3.执行构造方法. 4.返回相关的地址给相关的对象. this的本质 ...