1. 基本概念

线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。

线程是独立调度和分派的基本单位。线程可以为操作系统内核调度的内核线程,如Win32线程;由用户进程自行调度的用户线程,如Linux平台的POSIX Thread;或者由内核与用户进程,如Windows 7的线程,进行混合调度。

同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。

一个进程可以有很多线程,每条线程并行执行不同的任务。

在多核或多 CPU,或支持Hyper-threading的CPU上使用多线程程序设计的好处是显而易见,即提高了程序的执行吞吐率。在单CPU单核的计算机上,使用多线程技术,也可以把进程中负责I/O处理、人机交互而常被阻塞的部分与密集计算的部分分开来执行,编写专门的workhorse线程执行密集计算,从而提高了程序的执行效率。(摘自百度百科)

线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。

每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。

当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:

调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生。

非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。

2 定义任务

线程可以驱动任务,因此需要一种描述任务的方式。创建新执行线程有两种方法。一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。

2.1 重写Thread类的的run方法

public class Thread extends Object implements Runnable

查看 API文档可知:其实 Thread 也是实现 Runable 接口的类

 1 package thread;
 2
 3 public class liftOff implements Runnable {
 4     protected int countDown=10;
 5     private static int taskCount=0;
 6     private final int id=taskCount++;
 7     public liftOff() {}
 8     public liftOff(int countDown) {
 9         this.countDown=countDown;
10     }
11     public String status() {
12         return "#"+id+"("+(countDown>0?countDown:"liftOff")+"),";
13     }
14     @Override
15     public void run() {
16         // TODO Auto-generated method stub
17         while(countDown-->0) {
18             System.out.print(status());
19             Thread.yield();
20         }
21     }
22
23 }

package thread;public class basicThread {public static void main(String[] args){Thread t=new Thread(new liftOff());t.start();System.out.println("Waiting for liftOFF");}
}//Output
/*#0(9),#0(8),#0(7),#0(6),#0(5),#0(4),#0(3),#0(2),#0(1),#0(liftOff),#1(9),#1(8),#1(7),#1(6),#1(5),#1(4),#1(3),#1(2),#1(1),#1(liftOff),#2(9),#2(8),#2(7),#2(6),#2(5),#2(4),#2(3),#2(2),#2(1),#2(liftOff),#3(9),#3(8),#3(7),#3(6),#3(5),#3(4),#3(3),#3(2),#3(1),#3(liftOff),#4(9),#4(8),#4(7),#4(6),#4(5),#4(4),#4(3),#4(2),#4(1),#4(liftOff),*/

View Code

2.2 声明实现 Runnable 接口

 1 package thread;
 2
 3 public class mainThread {
 4     public static void main(String[] args) {
 5         liftOff launch=new liftOff();
 6         launch.run();
 7     }
 8 }
 9 /* Output   #0(9),#0(8),#0(7),#0(6),#0(5),#0(4),#0(3),#0(2),#0(1),#0(liftOff),
10 */

从运行结果可以看出,并发是每个线程是互不影响的。

异步时,new Thread的弊端如下:

a. 每次new Thread新建对象性能差。
b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
c. 缺乏更多功能,如定时执行、定期执行、线程中断。
相比new Thread,Java提供的四种线程池的好处在于:
a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。
b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
c. 提供定时执行、定期执行、单线程、并发数控制等功能。

2.3 使用 Executor接口

执行已提交的 Runnable 任务的对象。此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节、调度等)分离开来的方法。通常使用 Executor 而不是显式地创建线程。

不过,Executor 接口并没有严格地要求执行是异步的。在最简单的情况下,执行程序可以在调用者的线程中立即运行已提交的任务: 更常见的是,任务是在某个不是调用者线程的线程中执行的。以下执行程序将为每个任务生成一个新线程。

许多 Executor 实现都对调度任务的方式和时间强加了某种限制。以下执行程序使任务提交与第二个执行程序保持连续,这说明了一个复合执行程序。

此包中提供的 Executor 实现实现了 ExecutorService,这是一个使用更广泛的接口。ThreadPoolExecutor 类提供一个可扩展的线程池实现。Executors 类为这些 Executor 提供了便捷的工厂方法。

内存一致性效果:线程中将 Runnable 对象提交到 Executor 之前的操作 happen-before 其执行开始(可能在另一个线程中)。

Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行

 1)使用CachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。示例代码如下:

 1 package thread;
 2
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5
 6 public class cachedThreadPool {
 7     public static void main(String[] args) {
 8         ExecutorService exec = Executors.newCachedThreadPool();
 9         for (int i = 0; i < 5; i++) {
10             exec.execute(new liftOff());
11         }
12         exec.shutdown();
13
14     }
15 }/*Output #1(9),#0(9),#1(8),#0(8),#3(9),#4(9),#2(9),#0(7),#2(8),#3(8),#0(6),#1(7),#0(5),#3(7),#0(4),#2(7),#4(8),#1(6),#3(6),#2(6),#4(7),#1(5),#3(5),#1(4),#2(5),#0(3),#4(6),#3(4),#1(3),#2(4),#0(2),#4(5),#1(2),#2(3),#1(1),#3(3),#2(2),#4(4),#0(1),#1(liftOff),#2(1),#0(liftOff),#3(2),#2(liftOff),#4(3),#3(1),#4(2),#3(liftOff),#4(1),#4(liftOff),
16 */

  2)使用FixedThreadPool

  创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:

 1 package thread;
 2
 3
 4
 5 import java.util.concurrent.ExecutorService;
 6 import java.util.concurrent.Executors;
 7
 8 public class fixedThreadPool {
 9     public static void main(String[] args) {
10         ExecutorService exec = Executors.newFixedThreadPool(5);
11         for (int i = 0; i < 5; i++) {
12             exec.execute(new liftOff());
13         }
14         exec.shutdown();
15
16     }
17 }
18 /*Output #1(9),#0(9),#1(8),#0(8),#3(9),#4(9),#2(9),#0(7),#2(8),#3(8),#0(6),#1(7),#0(5),#3(7),#0(4),#2(7),#4(8),#1(6),#3(6),#2(6),#4(7),#1(5),#3(5),#1(4),#2(5),#0(3),#4(6),#3(4),#1(3),#2(4),#0(2),#4(5),#1(2),#2(3),#1(1),#3(3),#2(2),#4(4),#0(1),#1(liftOff),#2(1),#0(liftOff),#3(2),#2(liftOff),#4(3),#3(1),#4(2),#3(liftOff),#4(1),#4(liftOff),
19
20  * */

  3)使用SingleThreadPool

  创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:

package thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class singleThreadPool {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
exec.execute(new liftOff());
}
exec.shutdown();

}
}/*#0(9),#0(8),#0(7),#0(6),#0(5),#0(4),#0(3),#0(2),#0(1),#0(liftOff),
#1(9),#1(8),#1(7),#1(6),#1(5),#1(4),#1(3),#1(2),#1(1),#1(liftOff),
#2(9),#2(8),#2(7),#2(6),#2(5),#2(4),#2(3),#2(2),#2(1),#2(liftOff),
#3(9),#3(8),#3(7),#3(6),#3(5),#3(4),#3(3),#3(2),#3(1),#3(liftOff),
#4(9),#4(8),#4(7),#4(6),#4(5),#4(4),#4(3),#4(2),#4(1),#4(liftOff),
*/

  

转载于:https://www.cnblogs.com/tianliang94/p/10633797.html

并发--基本的线程机制相关推荐

  1. 【Java 并发编程】线程池机制 ( ThreadPoolExecutor 线程池构造参数分析 | 核心线程数 | 最大线程数 | 非核心线程存活时间 | 任务阻塞队列 )

    文章目录 前言 一.ThreadPoolExecutor 构造参数 二.newCachedThreadPool 参数分析 三.newFixedThreadPool 参数分析 四.newSingleTh ...

  2. 【Java 并发编程】线程池机制 ( 线程池示例 | newCachedThreadPool | newFixedThreadPool | newSingleThreadExecutor )

    文章目录 前言 一.线程池示例 二.newCachedThreadPool 线程池示例 三.newFixedThreadPool 线程池示例 三.newSingleThreadExecutor 线程池 ...

  3. 探索 ConcurrentHashMap 高并发性的实现机制

    简介 ConcurrentHashMap 是 util.concurrent 包的重要成员.本文将结合 Java 内存模型,分析 JDK 源代码,探索 ConcurrentHashMap 高并发的具体 ...

  4. Java并发编程之线程池及示例

    1.Executor 线程池顶级接口.定义方法,void execute(Runnable).方法是用于处理任务的一个服务方法.调用者提供Runnable 接口的实现,线程池通过线程执行这个 Runn ...

  5. 探索 ConcurrentHashMap 高并发性的实现机制--转

    ConcurrentHashMap 是 Java concurrent 包的重要成员.本文将结合 Java 内存模型,来分析 ConcurrentHashMap 的 JDK 源代码.通过本文,读者将了 ...

  6. 并发编程-11线程安全策略之线程封闭

    文章目录 脑图 概述 线程封闭的三种方式 示例 堆栈封闭 ThreadLocal Step1. ThreadLocal操作类 Step2. 自定义过滤器 Step3. 注册拦截器,配置拦截规则 Ste ...

  7. c++ 线程池_基础篇:高并发一瞥,线程和线程池的总结

    进程是执行程序的实体,拥有独属的进程空间(内存.磁盘等).而线程是进程的一个执行流程,一个进程可包含多个线程,共享该进程的所有资源:代码段,数据段(全局变量和静态变量),堆存储:但每个线程拥有自己的执 ...

  8. java并发编程与线程安全

    2019独角兽企业重金招聘Python工程师标准>>> 什么是线程安全 如果对象的状态变量(对象的实例域.静态域)具有可变性,那么当该对象被多个线程共享时就的考虑线程安全性的问题,否 ...

  9. Java线程机制学习

    前面的文章中总结过Java中用来解决共享资源竞争导致线程不安全的几种常用方式: synchronized: ReentrantLock: ThreadLocal: 这些都是在简单介绍了基本用法的基础上 ...

最新文章

  1. rsyslog的配置文件使用方法
  2. 车路协同让城市更智慧
  3. python 散点图_Python绘制散点图
  4. Android 插件技术实战总结
  5. JMS : Java Message Service (Java消息服务)之一 [转]
  6. java按比例之原图生成缩略图
  7. 6月国产网络游戏审批信息公布 共计86款游戏过审
  8. 【CS231n_2017】2-Image Classification
  9. HttpWebRequest中GetResponse或者说GetRequestStream偶尔超时,或者是各种操作超时造成的假死的一些解决方案...
  10. 做一款仿映客的直播App
  11. SVM笔记(一)硬间隔SVM
  12. google crx Hoxx 下载
  13. 计算机技术三大领域,量化投资策略的运用
  14. antd 踩坑之 javascriptEnabled配置
  15. C5750X7R2E105K230KA(电容器)MSP430F5249IRGCR微控制器资料
  16. Beyong Compare使用
  17. 我是没有志气的程序员
  18. LK32T102简述
  19. neat算法做监督学习(Python)
  20. 计算机主要配件型号价格,你知道电脑的“五大主要部件”的选择吗?

热门文章

  1. Git 服务器镜像迁移 - 携带提交日志,tag,branch。。
  2. Selenium Web 自动化 - Selenium常用API
  3. 转;说说AngularJS中的$parse和$eval
  4. Docker容器的原理与实践(上)
  5. JavaScript 工作原理之十一-渲染引擎及性能优化小技巧
  6. c++11 线程:让你的多线程任务更轻松
  7. 数据结构之链表、栈和队列 java代码实现
  8. application/x-www-form-urlencoded multipart/form-data text/plain 的区别和作用
  9. 比特币现金(BCH)将在2018年占据主导地位
  10. es6之扩展运算符...