Java 多线程(基础篇)
Posted offerNotFound
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 多线程(基础篇)相关的知识,希望对你有一定的参考价值。
本文记录于阿里一群大佬们手码的书:《深入浅出Java多线程》
线程与进程的区别:
- 进程是一个独立的运行环境,而线程是在进程中执行的一个任务
- 进程单独占有一定的内存地址空间,所以进程间存在内存隔离,数据是分开的,数据共享复杂但是同步简单,各个进程之间互不干扰;而线程共享所属进程占有的内存地址空间和资源,数据共享简单,但是同步复杂。
- 进程单独占有一定的内存地址空间,一个进程出现问题不会影响其他进程,不影响主程序的稳定性,可靠性高;一个线程崩溃可能影响整个程序的稳定性,可靠性较低。
- 进程单独占有一定的内存地址空间,进程的创建和销毁不仅需要保存寄存器和栈信息,还需要资源的分配回收以及页调度,开销较大;线程只需要保存寄存器和栈信息,开销较小。
- 进程是操作系统进行资源分配的基本单位,而线程是操作系统进行调度的基本单位。
- 一个进程包含多个线程
操作系统线程主要有以下三个状态:
- 就绪状态:线程正在等待使用CPU,经调度程序调用之后可进入执行状态。
- 执行状态:线程正在使用CPU。
- 等待状态:线程正在等待其他资源。
Java 线程的6中状态:
NEW(初始)
:新创建了一个线程对象,但还没有调用start()方法。RUNNABLE(执行)
:线程正在执行当中(执行状态),也有可能在等待CPU分配资源(就绪状态)。WATING(等待)
:线程处于等待状态,等待其它线程做成指定动作(唤醒或中断)。
调用如下3个方法会使线程进入等待状态:
Object.wait()
:调用wait()方法前线程必须持有对象的锁,wait 方法会释放锁;
Thread.join()
:不会释放锁,会一直等待当前线程执行完毕,底层调用的是wait方法;
LockSupport.park()
:除非获得调用许可,否则禁用当前线程进行线程调度。
TIME_WATING(超时等待)
:线程等待一个具体的时间,时间到后会被自动唤醒。
调用如下方法会使线程进入超时等待状态:
Thread.sleep(long millis)
:不会释放锁,时间一到就继续回到执行状态、Object.wait(long timeout)
、Thread.join(long millis)
等等
BLOCKED(阻塞)
:线程阻塞于锁,正等待锁的释放以进入同步区。。TERMINATED(终止)
:线程执行完毕。
线程中断:
线程中断机制是一种协作机制。需要注意,通过中断操作并不能直接终止一个线程,而是通知需要被中断的线程自行处理。
Java 中断的三个方法:
Thread.interrupt()
:中断线程。这里的中断线程并不会立即停止线程,而是设置线程的中断状态为true(默认是flase);Thread.interrupted()
:测试当前线程是否被中断。线程的中断状态受这个方法的影响,意思是调用一次使线程中断状态设置为true,连续调用两次会使得这个线程的中断状态重新转为false;Thread.isInterrupted()
:测试当前线程是否被中断。与上面方法不同的是调用这个方法并不会影响线程的中断状态。
在线程中断机制里,当其他线程通知需要被中断的线程后,线程中断的状态被设置为true,但是具体被要求中断的线程要怎么处理,完全由被中断线程自己而定,可以在合适的实际处理中断请求,也可以完全不处理继续执行下去。
Java 线程间的通信
注意:线程间的通信建立于都是同一把锁的情况下。
Java多线程的等待/通知机制是基于Object类的wait()
方法和notify()
, notifyAll()
方法来实现的。
notify()方法会随机叫醒一个正在等待的线程,而notifyAll()会叫醒所有正在等待的线程。
wait()
方法与 sleep()
方法的区别:
- wait会释放CPU资源,也会释放锁;sleep会释放CPU资源,但不会释放锁。
- wait可以不声明等待时间;但sleep必须声明睡眠时间。
- wait必须放在同步块或同步方法中;而sleep可以再任意位置。
以上是关于Java 多线程(基础篇)的主要内容,如果未能解决你的问题,请参考以下文章