Java多线程

什么是多线程

提到线程,不得不先说一下什么是进程。

进程就是正在运行的程序。当一个程序进入内存运行时,即变成一个进程。每个进程都有独立的代码和数据空间(进程上下文)。一个进程包含1--n个线程。一个线程不能独立的存在,它必须是进程的一部分。

线程是进程的组成部分,一个进程可以有多个线程,但一个线程必须只有一个父进程。线程可以拥有自己的栈,自己的程序计数器和自己的局部变量,但不拥有父进程资源,处理资源一般是父进程把资源(对象指针)传给线程,它与父进程的其他线程共享该进程所拥有的全部资源。

多线程就是同一进程可以同时并发处理多个线程,它们独立运行,互不妨碍。多线程能满足程序员编写高效率的程序来达到充分利用CPU的目的。

一个线程的生命周期

线程是一个动态执行的过程,它也有一个从产生到死亡的过程。下图显示了一个线程完整的生命周期。

下面是对其中名词的解释:

新建状态(New):新创建了一个线程对象。

就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。

运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。

阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

(1)等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁)

(2)同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。

(3)其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

线程睡眠(sleep()):Thread.sleep(long millis)方法,使线程转到阻塞状态。millis参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,就转为就绪(Runnable)状态。sleep()平台移植性。注意,sleep是不会释放持有的锁。

线程加入(join()):执行threadObj.join()方法,父线程(主线程)会等到threadObj运行终止后再执行。在当前线程(主线程)中调用另一个线程(子线程)的join()方法,则当前线程转入阻塞状态,直到另一个线程运行结束,当前线程再由阻塞转为就绪状态。也就是主线程中,子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。

线程让步(yield())Thread.yield()方法,暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程。yield()让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

线程等待/线程唤醒Object类中的wait()方法,导致当前的线程等待,直到其他线程调用此对象的notify()方法或notifyAll()唤醒方法。要注意的是:

(1)obj.wait(),与obj.notify()必须要与synchronized(obj)一起使用,也就是wait与notify是针对已经获取了obj锁进行操作,从语法角度来说就是obj.wait(),obj.notify()必须在synchronized(obj){...}语句块内。

(2)当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态。

(3)当执行notify()/notifyAll()方法时,会唤醒一个处于等待该对象锁的线程,然后继续往下执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁。

(0)

相关推荐

  • 并发编程最基础的12个面试连环炮,你答得上几个?

    关注"Java后端技术全栈" 回复"000"获取大量电子书 在面试中,关于并发编程基础部分,如果你能接住以下12个连环炮,至少你的并发编程基础还是不错的. 本文 ...

  • 这样学 Python 多线程与进程(一)

    第一时间获取 Python 技术干货! 阅读文本大概需要 5 分钟. 众所周知,Python 中的多线程是一个假的多线程,对于多核 CPU,由于受限于 GIL 全局解释锁,同一时刻只能有一个线程在运行 ...

  • JAVA多线程学习笔记整理

    多线程: 三种创建方法 继承Thread类,以线程运行内容重写run方法,创建Thread对象并用start方法启动该线程. (匿名内部类) (Lambda表达式) 实现Runable接口,以线程运行 ...

  • Java多线程访问Synchronized同步方法的八种使用场景

    简介 本文将介绍7种同步方法的访问场景,我们来看看这七种情况下,多线程访问同步方法是否还是线程安全的.这些场景是多线程编程中经常遇到的,而且也是面试时高频被问到的问题,所以不管是理论还是实践,这些都是 ...

  • Java多线程(3):wait()/notify()实例

    下面是代码实例 1 public class WaitDemo implements Runnable { 2 3 private Object lock; 4 5 public WaitDemo(O ...

  • Java多线程(2):线程加入/join()

    线程加入 join()方法,等待其他线程终止.在当前线程(主线程)中调用另一个线程(子线程)的join()方法,则当前线程转入阻塞状态,直到另一个线程运行结束,当前线程再由阻塞转为就绪状态. 也就是主 ...

  • Java多线程(1):3种常用的实现多线程类的方法

    (1) 继承java.lang.Thread类(Thread也实现了Runnable接口) 继承Thread类的方法是比较常用的一种,如果说你只是想起一条线程.没有什么其它特殊的要求,那么可以使用Th ...

  • Java多线程上下文传递在复杂场景下的实践

    一.引言 海外商城从印度做起,慢慢的会有一些其他国家的诉求,这个时候需要我们针对当前的商城做一个改造,可以支撑多个国家的商城,这里会涉及多个问题,多语言,多国家,多时区,本地化等等.在多国家的情况下如 ...

  • java多线程并发实例

    package cn.crhms.modelsystem.utils;import java.util.ArrayList;import java.util.List;import java.util ...

  • java多线程技术从入门到精通,40个Java多线程问题总结

    这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题. 这些多线程的问题,有些来源于各大网站.有些来源于自己的思考.可能有些问题网上有.可能有些问题对应的答案也有.也可能有些各位网友也 ...

  • 一定要偷偷学,偷偷进步!腾讯内部首发Java多线程、高并发、设计模式“满级”笔记

    Java编程语言是工业级的编程语言,在诸多应用.诸多场景下被广泛使用,多线程技术作为Java语言和应用的基础能力,对其的学习.理解和掌握,不仅仅能够提升我们的技能,更能作为我们更好地理解面向对象编程. ...