线程的常用知识(包括 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的 ...
随机推荐
- Binding(五):多路绑定
Binding不止能绑定一个源,它还能绑定多个源,这就是我们这节要讲的多路绑定:MultiBinding. 使用多路绑定跟一般的绑定还是有区别的,首先它并不能很好的在标记扩展中使用,另外,使用多路绑定 ...
- AcWing 220. 最大公约数
给定整数N,求1<=x,y<=N且GCD(x,y)为素数的数对(x,y)有多少对. GCD(x,y)即求x,y的最大公约数. #include<bits/stdc++.h> u ...
- RabbitMQ消息可靠性传输
消息的可靠性投递是使用消息中间件不可避免的问题,不管是使用kafka.rocketMQ或者rabbitMQ,那么在RabbitMQ中如何保证消息的可靠性投递呢? 先再看一下RabbitMQ消息传递的流 ...
- Docker:docker部署Sqlite3数据库
1.依赖Ubuntu系统安装sqlite3生成镜像 dockerfile文件 FROM ubuntu:trusty RUN sudo apt-get -y update RUN sudo apt-ge ...
- CG-CTF Our 16bit Games
一.放到xp上面跑,发现是一个图形界面的飞机游戏...估计是分数到达多少,然后就可以输出flag. 打开ida,一脸懵逼,主要这玩意16位,我直接静态调试了 发现很多汇编代码,有点懵逼,在最下方的地方 ...
- XSS一些总结
XSS一些总结 除了script以外大多标签自动加载触发JS代码大多用的都是on事件,以下标签都可以用下面的方法去打Cookie以及url等 常见标签 <img><input> ...
- DHCP工作原理
DHCP:Dynamic Host Configurtion Protocol DHCP的工作原理(UDP) 1.客户端:首先会发送给一个dhcp discovery(广播)报文,报文中的2层和3层都 ...
- external-resizer 源码分析/pvc 扩容分析
kubernetes ceph-csi分析目录导航 基于tag v0.5.0 https://github.com/kubernetes-csi/external-resizer/releases/t ...
- ffmpeg入门篇-滤镜的基本使用
转发自白狼栈:查看原文 滤镜 什么是滤镜?百度百科介绍说"滤镜主要是用来实现图像的各种特殊效果......". 我们最早在ffmpeg是如何转码的一文中了解过滤镜,来回顾下当时的转 ...
- 机器学习Sklearn系列:(五)聚类算法
K-means 原理 首先随机选择k个初始点作为质心 1. 对每一个样本点,计算得到距离其最近的质心,将其类别标记为该质心对应的类别 2. 使用归类好的样本点,重新计算K个类别的质心 3. 重复上述过 ...