前言

线程作为现代操作系统调度的最小单元,多个线程能够同时执行,这将显著提高程序的性能,而且在当前多核CPU的环境下也能更好的利用资源。Java提供了对多线程的良好支持。线程是多线程的基础。

使用多线程的原因:1. 计算机的核心越来越多,更好的利用硬件资源。2. 更快的响应时间,对于复杂的业务逻辑能够多路进行,当然如果你只是打印一句"Hello World"确实"不需要多线程" 3. Java 已经为多线程编程提供了良好 的编程模型。开发人员可以直接使用,不必重复造轮子。

进程和线程

现代操作系统在允许一个程序时,会为其创建一个进程。而操作系统最小的调度单元是线程,一个进程中可以创建多个线程。

这些线程拥有各自的计数器,堆栈和局部变量。这些线程能够访问进程中共享的内存变量。

Daemon(守护线程) 线程是一种支持型的线程,它主要被作用于程序中后台调度以及支持性工作。用个比较通俗的比喻,任何一个守护线程都是整个JVM中所有非守护线程的保姆。守护线程最典型的应用就是 GC (垃圾回收器)

只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。

创建线程的方式

继承Thread 实现Runable

  • 继承Thread 重写run()方法
  • 实现Runnable接口重写run()方法

阿里巴巴Java 开发规范中强制规定 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”(CPU上下文切换)的问题。

线程 线程的状态

  • NEW 创建未运行中
  • RUNNING 调用start() 方法后运行中的状态
  • WAITING 等待状态,需notify() 方法通知后返回运行中状态
  • TIME WAITING 超时等待,在给定时间后返回运行中状态
  • BLOCKED 为获取到锁,进入到阻塞状态,在阻塞获取到锁后返回运行中状态
  • TERMINATED 终止状态

线程的状态转换

启动停止线程

  • start() 方法用于启动线程,run()方法是执行体,线程start()启动后会执行run() 方法体内的程序。

停止线程

  • 中断

    • 它表示一个运行中的线程是否被其他线程进行中断操作(被其他线程停止)
    • 其他线程通过调用该线程的 interrupt() 方法对其进行中断操作
    • 线程通过isInterrupted()方法(返回中断标识符)来进行判断是否被中断,
  • 安全的终止线程
    • 类似于中断,通过一个变量的控制来停止线程
      private static class Runner implements Runnable {
      
          private volatile boolean on = true;
      
          @Override
      public void run() {
      while (on && !Thread.currentThread().isInterrupted()) {
      // do something
      }
      } public void stopRunner() {
      on = false;
      }
      }

sleep() 函数线程会让出CPU,给其他需要CPU资源的线程使用

线程和线程之间的通信

线程和线程之间是如何通信和进行协作的呢

方式:

  • volatile 和 synchronized 关键字

    • 多个线程在自己内部都有共享变量的拷贝进行使用,修改共享变量,然后其他线程立刻感知到共享变量的修改
  • 等待通知机制

    • 等待通知机制是两个线程通过一个对象来进行交互,以这个对象作为媒介。一个线程A调用这个对象的wait() 方法进行等待状态,另一个线程B调用notifyAll进行通知。线程A接收到通知返回 进行后续操作。而且调用wait() 方法会释放这个对象的锁。
    • Object 类自带的等待/通知方法
      • notify() 通知一个在对象上等待的线程
      • notifyAll() 通知所有等待在该对象上的线程
      • wait() 调用该方法的线程进入WAITING状态,等待他人通知或中断才会返回
      • wait(long) 超时等待,可以选择等待的时间
      • wait(long,int) 超时等待,对于超时时间进行更细粒度的控制
    • 如何传参?通过共享变量
  • 管道输入/输出流

    • 管道输入/输出流用于线程之间的数据传输。包括了以下四种实现:PipedOutputStream、PipedInputStream、PipedReader、PipedWriter 前两种面向字节,后两种面向字符
    • 对于Poped类型的流,必须先进行绑定,也就是调用connect() 方法。
  • join()方法

    • 线程A 和线程thread ,当线程A执行了thread.join()语句。线程A等待thread线程终止后才从thread.join() 返回。
    • join(longmillis) join(long millis,int nanos)
  • ThreadLocal

    • 线程变量,每个线程可以绑定一个ThreadLocal。ThreadLocal是一个以ThreadLocal对象为键,任意对象为值的存储结构。
    • 对于同一个线程。set() 方法来设置一个值,get()方法获取原先设置的值。

分享一道常见面试题三个线程交替打印从1-100

// 使用 synchronized notifyAll() 实现 wait() 实现
public class PrintNums { private Object lock = new Object();
private volatile int curNum = 1;
private volatile String curThread = "1"; class Runner implements Runnable {
@Override
public void run() {
while (curNum < 101) {
synchronized (lock) {
while (!Thread.currentThread().getName().equals(curThread)) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (curThread.equals("3")) {
curThread = "1";
} else {
curThread = String.valueOf(Integer.valueOf(curThread) + 1);
}
if (curNum < 101) {
System.out.println(
"current thread: " + Thread.currentThread().getName()
+ " cur num: " + curNum++);
} lock.notifyAll();
}
}
}
} public static void main(String[] args) {
PrintNums print = new PrintNums();
Thread thread1 = new Thread(print.new Runner(), "1");
Thread thread2 = new Thread(print.new Runner(), "2");
Thread thread3 = new Thread(print.new Runner(), "3"); thread1.start();
thread2.start();
thread3.start(); System.out.println("main terminate");
} }

运行结果:

main terminate
current thread: 1 cur num: 1
current thread: 2 cur num: 2
current thread: 3 cur num: 3
current thread: 1 cur num: 4
current thread: 2 cur num: 5
current thread: 3 cur num: 6

References

  • 《Java并发编程的艺术》

Java多线程之线程的更多相关文章

  1. Java多线程之线程其他类

    Java多线程之线程其他类 实际编码中除了前面讲到的常用的类之外,还有几个其他类也有可能用得到,这里来统一整理一下: 1,Callable接口和Future接口 JDK1.5以后提供了上面这2个接口, ...

  2. Java多线程之线程的通信

    Java多线程之线程的通信 在总结多线程通信前先介绍一个概念:锁池.线程因为未拿到锁标记而发生的阻塞不同于前面五个基本状态中的阻塞,称为锁池.每个对象都有自己的锁池的空间,用于放置等待运行的线程.这些 ...

  3. Java多线程之线程的同步

    Java多线程之线程的同步 实际开发中我们也经常提到说线程安全问题,那么什么是线程安全问题呢? 线程不安全就是说在多线程编程中出现了错误情况,由于系统的线程调度具有一定的随机性,当使用多个线程来访问同 ...

  4. Java多线程之线程的控制

    Java多线程之线程的控制 线程中的7 种非常重要的状态:  初始New.可运行Runnable.运行Running.阻塞Blocked.锁池lock_pool.等待队列wait_pool.结束Dea ...

  5. Java多线程父子线程关系 多线程中篇(六)

    有的时候对于Java多线程,我们会听到“父线程.子线程”的概念. 严格的说,Java中不存在实质上的父子关系 没有方法可以获取一个线程的父线程,也没有方法可以获取一个线程所有的子线程 子线程的消亡与父 ...

  6. 关于Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇高质量的博文)

    Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文) 前言:在学习多线程时,遇到了一些问题,这里我将这些问题都分享出来,同时也分享了几篇其他博客主的博客,并且将我个人的理解也分享 ...

  7. Java多线程02(线程安全、线程同步、等待唤醒机制)

    Java多线程2(线程安全.线程同步.等待唤醒机制.单例设计模式) 1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量 ...

  8. JAVA多线程之线程间的通信方式

    (转发) 收藏 记 周日,北京的天阳光明媚,9月,北京的秋格外肃穆透彻,望望窗外的湛蓝的天,心似透过栏杆,沐浴在这透亮清澈的蓝天里,那朵朵白云如同一朵棉絮,心意畅想....思绪外扬, 鱼和熊掌不可兼得 ...

  9. java多线程与线程间通信

    转自(http://blog.csdn.net/jerrying0203/article/details/45563947) 本文学习并总结java多线程与线程间通信的原理和方法,内容涉及java线程 ...

  10. java多线程之 ---- 线程死锁

    java多线程之线程死锁 产生死锁的主要原因: 由于系统资源不足. 进程执行推进的顺序不合适. 资源分配不当等. 假设系统资源充足.进程的资源请求都可以得到满足,死锁出现的可能性就非常低.否则就会因争 ...

随机推荐

  1. VS Code 搭建合适的 markdown 文档编写环境

    写在开头,之前我是使用Gitee与Github作为图床和Picgo搭配Typora使用的 ,但因为最近觉得这样还是稍微比较繁琐,然后因为VS Code是我的主要文本编辑器.Cpp,Python等均是在 ...

  2. ElasticSearch 集群 & 数据备份 & 优化

    ElasticSearch 集群相关概念 ES 集群颜色状态 ①. - 红色:数据都不完整 ②. - 黄色:数据完整,但是副本有问题 ③. - 绿色:数据和副本全都没有问题 ES 集群节点类型 ①. ...

  3. 涂颜色的RPG问题

    长度为n的方格,刷3种颜色的颜料,相邻的方格颜料颜色不能相同,且首尾方格颜色不能相同.每个方格必须涂色.计算一共有多少种涂色方式. 解题思路:(1)f(1)=3,f(2)=6,f(3)=6 (2)如果 ...

  4. 如何在 VSCODE 中高效使用 R 语言

    VSCODE 配置 R 一.功能特性展示 之前一直在用 Rstudio 来编写 R,也尝试用过 Pycharm 配置 R 环境. 但是由于现在需求要同时满足 Python,R 和网站要同时开发,为了避 ...

  5. React & Special Props Warning

    React & Special Props Warning key & ref demo index.js:1 Warning: Comment: key is not a prop. ...

  6. Python3 & Decorators with arguments & @Decorators with arguments bug

    Python3 & Decorators with arguments & @Decorators with arguments bug @Decorators with argume ...

  7. how to write an ebook that can support published by format PDF, Epub, Mobi and so on

    how to write an ebook that can support published by format PDF, Epub, Mobi and so on 如何写一本自己的电子书,支持各 ...

  8. mobile app & ppi & dpi & px

    mobile app & ppi & dpi & px How do dp, dip, dpi, ppi, pixels and inches relate? https:// ...

  9. CI / CD in Action

    CI / CD in Action Continuous Integration (CI) & Continuous Delivery (CD) https://github.com/mark ...

  10. SVG 2 & SVG & getPointAtLength & getPathSegAtLength

    SVG 2 & SVG & getPointAtLength & getPathSegAtLength getPointAtLength SVG 1.x https://dev ...