线程的常用知识(包括 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的 ...
随机推荐
- 3、oracle表空间及索引操作
3.1.创建表空间和用户授权: 1.创建表空间: CREATE TABLESPACE <表空间名> LOGGING DATAFILE '<存放路径>' SIZE 50M AUT ...
- 箭头函数中this指向问题
// 问题:箭头函数中的this是如何查找的? // 答案:向外层作用域中,一层层查找this,直到有this的定义
- 暑假自学java第二天
今天学习了一些java规则 一个java源文件的公开类只能有一个,而且必学和源文件名相同. 了解到java的标识符规范,这对以后的团队协作有很大作用. 标识符规则和c++还是很相似的 java中的字面 ...
- bugkuCTF
这题说实话我一脸懵逼,计网还没学的我,瑟瑟发抖,赶紧去百度. 思路分析: 涉及到域名解析,也就是dns服务,看了看writeup,都是修改host文件,百度了下host文件的作用,才明白了 host文 ...
- Spring cloud中相关的工具和库
spring: 是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架. spring mvc: spring集成的mvc开发框架. spring ...
- Linux | 文件编辑命令
cat cat 命令是是一次性显示文件的所有内容 cat 是 concatenate 的缩写,表示:连接/串联 cat 文件名 可以看到,cat 命令是一次性显示出所有的文件内容,这就导致了,有的文件 ...
- Python 操作 MySQL 的5种方式
不管你是做数据分析,还是网络爬虫,Web 开发.亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文章介绍 Python 操作 MySQL 的5种方式,你可以在实 ...
- GYM101471D「ICPC2017 WF」Money for Nothing
「ICPC2017 WF」Money for Nothing 传送门 我们可将生产商和消费商都看成二维平面上的点,其坐标分别为 \((d_i,p_i)\),\((e_i,q_i)\). 那么问题转变为 ...
- 手写笔记变PDF-几行代码变命令行程序为图形化界面
前言 最近发现了一个非常不错的Python类库----Gooey, https://github.com/chriskiehl/Gooey 在它的帮助下我们可以非常方便的将一个命令行程序升级成一个图形 ...
- Function.identity()
Java 8允许在接口中加入具体方法.接口中的具体方法有两种,default方法和static方法,identity()就是Function接口的一个静态方法.Function.identity()返 ...