本次内容列表:

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/阻塞/并发/锁等)的更多相关文章

  1. Thread线程的基础知识及常见疑惑点

    引言 相信各位道友在平时工作中已经很少直接用到Thread线程类了,现在大多是通过线程池或者一些多线程框架来操作线程任务,但我觉得还是有必要了解清楚Thread线程类中各种方法的含义,了解了底层才能更 ...

  2. JAVA常用知识总结(九)——线程

    sleep和wait的区别? sleep()来自Thread类,和wait()来自Object类.调用sleep()方法的过程中,线程不会释放对象锁.而 调用 wait 方法线程会释放对象锁 slee ...

  3. {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器

    Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...

  4. C#线程同步(1)- 临界区&Lock

    文章原始出处 http://xxinside.blogbus.com/logs/46441956.html 预备知识:线程的相关概念和知识,有多线程编码的初步经验. 一个机会,索性把线程同步的问题在C ...

  5. 已看1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、多线程(并发编程)、I/O(NIO)、Socket、JDBC、XML、反射等。[泛型]\

    1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架.多线程(并发编程).I/O(NIO).Socket.JDBC.XML.反射等.[泛型]\1* ...

  6. C#线程系列讲座(2):Thread类的应用

    一.Thread类的基本用法 通过System.Threading.Thread类可以开始新的线程,并在线程堆栈中运行静态或实例方法.可以通过Thread类的的构造方法传递一个无参数,并且不返回值(返 ...

  7. Java程序员必备知识-多线程框架Executor详解

    为什么引入Executor线程池框架 new Thread()的缺点 每次new Thread()耗费性能 调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞 ...

  8. c# 线程浅析(代理 、Invoke、Lock)

    前言:本来想根据自己的经验总结一下c#线程相关的知识点, 写之前看了一些其他人的博客,发现自己也就掌握了不到三分之一....希望通过这次的博客将自己的知识点补充一下,写出更直白的博客和初学者分享. 这 ...

  9. [转]C#线程同步(1)- 临界区&Lock

    第一印象,C#关于线程同步的东西好多,保持了C#一贯的大杂烩和四不象风格(Java/Delphi).临界区跟Java差不多只不过关键字用lock替代了synchronized,然后又用Moniter的 ...

随机推荐

  1. 11、ssh自动化脚本编写

    11.1.如何一键自动化安装50台规模集群网站搭建: 1.自动化思路: kickstart无人值守安装linux系统(自动创建用户.密码.优化): 分发机上创建秘钥对.批量发走公钥(expect): ...

  2. 常用API文字版

    常用API Object类 jvm启动,默认导入的是java.lang包中的内容,该包下的内容不需要import进行导入. 概念 该类是java体系中的根类,所有对象都将该类作为直接或者间接父类 所有 ...

  3. SpringMVC(2)经典的HelloWorld实现

    我机器的开发环境为: Ubuntu12.04(不同操作系统对本系列项目没有影响): 开发工具:Eclipse For JavaEE: 数据库:MySql5.5.35; 运行环境:TomCat V7.0 ...

  4. ARTS第十二周

    1.Algorithm:每周至少做一个 leetcode 的算法题2.Review:阅读并点评至少一篇英文技术文章3.Tip:学习至少一个技术技巧4.Share:分享一篇有观点和思考的技术文章 以下是 ...

  5. nginx的基本使用

    下载: https://nginx.org/en/download.html  Window下安装: 下载好了之后直接解压就行了.(解压目录切记别含有中文) 启动:1️⃣直接双击nginx.exe2️ ...

  6. Spring Boot邮箱链接注册验证

    Spring Boot邮箱链接注册验证 简单介绍 注册流程 [1]前端提交注册信息 [2]后端接受数据 [3]后端生成一个UUID做为token,将token作为redis的key值,用户数据作为re ...

  7. 排列组合的实现(js描述)

    组合的实现 排列组合描述和公式 犹记得高中数学,组合表示C(m, n),意思为从集合m,选出n个数生成一项,总共有多少个项的可能?组合是无序的,排列是有序的.所以排列的项数量多于组合 排列A(n,m) ...

  8. OpenFaaS实战之一:部署

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  9. 小程序框架WePY 从入门到放弃踩坑合集

    小程序框架WePY 从入门到放弃踩坑合集 一点点介绍WePY 因为小程序的语法设计略迷, 所以x1 模块化起来并不方便, 所以x2 各厂就出了不少的框架用以方便小程序的开发, 腾讯看到别人家都出了框架 ...

  10. P4293 [WC2010]能量场

    P4293 [WC2010]能量场 题意 给你 \(n\) 个粒子,每个粒子有两个权值 \(m_i,c_i\) 每个相邻有序对 \((a,b)\) 会产生 \(m_am_b(c_a-c_b)\) 的贡 ...