线程的常用知识(包括 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的 ...
随机推荐
- nginx访问fastdfs文件 报错400 Bad Request
1.修改vi /etc/fdfs/mod_fastdfs.conf 2.将url_have_group_name = false 改为 url_have_group_name = true 3.重启 ...
- JDK1.8 ArrayList 源码解析
源码的解读逻辑按照程序运行的轨迹展开 Arraylist的继承&实现关系 打开ArrayList源码,会看到有如下的属性定义, ArrayList中定义的属性 /** * Default in ...
- 「CF1380G」 Circular Dungeon
CF1380G Circular Dungeon 看懂样例就能做. 虽然我瞪了 20 分钟 菜是原罪 首先可以将从每一个点出发所能获得的价值相加,再除以 \(n\) 就可以得到价值的期望. 所以问题转 ...
- Linux- RPM与yum软件包安装
Linux安装及管理程序一.Linux应用程序基础1)应用程序与系统命令的关系2)典型应用程序的目录结构3)常见的软件包封装类型二.RPM包管理工具① RPM软件包管理器Red-Hat Package ...
- WIN10技巧
1.快速打开"开始---自动启动"文件夹:开始--支行--shell:startup 2
- Scrapy框架安装与使用(基于windows系统)
"人生苦短,我用python".最近了解到一个很好的Spider框架--Scrapy,自己就按着官方文档装了一下,出了些问题,在这里记录一下,免得忘记. Scrapy的安装是基于T ...
- ES6 Class类
在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类.class 的本质是 function.它可以看作一个语法糖,让对象原型的写法更加清晰.更像面向对象编程的语法类 ...
- Spring RestTemplate 之exchange方法
●exchange方法提供统一的方法模板进行四种请求:POST,PUT,DELETE,GET (1)POST请求 String reqJsonStr = "{\"code\&quo ...
- 高版本(8以上)tomcat不支持rest中的delete和put方式请求怎么办
出现问题 当我们去访问delete方式和put方式: 后来才知道tomcat8以上是不支持delete方式和put方式 解决方法: 在跳转目标的jsp头文件上改为(加上了isErrorPage=&qu ...
- 【洛谷P2041 分裂游戏】数学+瞎蒙
分析 我们推不出n=3的图,开始猜测,答案在n>2时无解.(<-正解) AC代码 #include <bits/stdc++.h> using namespace std; i ...