java_basic
1 线程分类
1 用户线程
2 守候线程 守候线程却不独立于JVM,守候线程一般是由操作系统或者用户自己创建的。
主线程结束,JVM直接退出,守护线程不管是否运行结束都要伴随着JVM的退出而退出
2 并发与并行
并发 通俗的说,并发是多个任务交替执行,
并行 是多个任务同时执行。两者的关键在于“同时”这个关键词
3 创建线程得方式
1 继承 Thread
2 实现 Runnable
3 实现 Callable 接口通过 FutureTask 包装器来创建 Thread 此线程有返回值
4 线程池 实际也是实现 Thread
4 线程的生命周期
Thread.State 枚举类中 有6中状态 NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED
NEW 新建状态 尚未启动的线程的状态。如MyThread thread = new MyThread();,thread就处于NEW状态。
RUNNABLE 就绪状态(可运行状态)。可运行线程的线程状态。thread.start();后,thread就处在处于RUNNABLE状态。
RUNNABLE状态的某一线程可能正在Java虚拟机中运行,但它也可能正在等待操作系统中的其他资源,
比如CPU。一个线程在获得CPU的资源后,才可以执行任务,否则排队等待。
BLOCKED 阻塞状态。 线程因为某些原因暂时停止运行,它就进入了阻塞状态。直到某些条件发生,线程进入就绪状态,才有机会继续运行。
线程进入阻塞状态有如下原因:
运行时的线程调用某一对象的同步方法,若该对象的同步锁被别的线程占用,就只好进入阻塞状态。等到获得了同步锁,才能进入就绪状态。(API上只说了这一个原因)
线程执行I/O操作或进行远程通信时,会因为等待相关的资源而进入阻塞状态。等到获得了相关资源,才能进入就绪状态。(待确定)
WAITING 等待状态。某一等待线程的线程状态。处于等待状态的线程正等待另一个线程,以执行特定操作。
某一线程因为调用下列方法之一而处于等待状态:
不带超时值的Object.wait。已经在某一对象上调用了Object.wait()的线程正等待另一个线程,以便在该对象上调用Object.notify()或Object.notifyAll()。
不带超时值的Thread.join。已经调用了Thread.join()的线程正在等待指定线程终止。
LockSupport.park。
TIMED_WAITING 定时等待状态。具有指定等待时间的某一等待线程的线程状态。某一线程因为调用以下带有指定正等待时间的方法之一而处于定时等待状态:
Thread.sleep。线程执行了Thread.sleep(int n)方法,线程将在n毫秒内放弃CPU,然后进入就绪状态。
带有超时值的Object.wait。已经在某一对象上调用了Object.wait(long timeout)的线程正等待另一个线程,当对应的notify()被调用或者超出指定时间时线程重新进入就绪状态。
带有超时值的Thread.join。例如,已经调用了join(long millis)的线程正在等待指定线程终止。等待该线程终止的时间最长为millis毫秒。超时为 0 意味着要一直等下去。
LockSupport.parkNanos。
LockSupport.parkUntil。
TERMINATED 终止状态。已终止线程的线程状态。线程已经结束执行。
5 Thread
线程等待与唤醒(wait()、notify()/notifyAll()) 三个都是object 得方法
线程让步(yield())
线程休眠(sleep())
线程启动(start())
中断线程(interrupt())
线程优先级
线程等待(join())
守护线程
其他方法
wait() 使用wait方法有个条件:当前线程必须持有对象的锁。执行wait后,当前线程会失去对象的锁
状态变为WAITING或者TIMED_WAITING状态。
notify()/notifyAll() 使用notify方法有个条件:线程必须持有对象的锁
唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。通过以下三种方法之一,
线程可以成为此对象监视器的所有者:
- 通过执行此对象的同步实例方法。
- 通过执行在此对象上进行同步的 synchronized 语句的正文。
- 对于 Class 类型的对象,可以通过执行该类的同步静态方法。
yield() 暂停当前正在执行的线程对象,并执行其他线程。“暂停”代表着让出CPU,但不会释放锁 当前线程由运行状态变为就绪状态。
让自己或者其他线程运行,并不是单纯的让给其他线程 “运行状态”进入到“就绪状态”
sleep() sleep方法可以使正在执行的线程让出CPU,但不会释放锁。执行sleep方法后,当前线程由运行状态变为TIMED_WAITING状态。
不同点 | yield() | wait() | sleep() |
---|---|---|---|
说明 | 礼让yield | 等待 | 睡眠 |
锁状态 | 释放锁 | 释放锁 | 不释放锁 只是释放 cpu |
状态变化 | 状态变为就绪状态 | 状态变为WAITING状态 | 状态变为TIMED_WAITING状态 |
中断线 interrupt()
要中断一个Java线程,可调用线程类(Thread)对象的实例方法:interrupte();然而interrupte()方法并不会立即执行中断操作;
具体而言,这个方法只会给线程设置一个为true的中断标志(中断标志只是一个布尔类型的变量),而设置之后,
则根据线程当前的状态进行不同的后续操作。
(1) 如果是wait、sleep以及jion三个方法引起的阻塞,那么会将线程的中断标志重新设置为false,并抛出一个InterruptedException;
(2) 如果是java.nio.channels.InterruptibleChannel进行的io操作引起的阻塞,则会对线程抛出一个ClosedByInterruptedException;(待验证)
(3) 如果是轮询(java.nio.channels.Selectors)引起的线程阻塞,则立即返回,不会抛出异常。(待验证)
如果在中断时,线程正处于非阻塞状态,则将中断标志修改为true,而在此基础上,一旦进入阻塞状态,
则按照阻塞状态的情况来进行处理;例如,一个线程在运行状态中,其中断标志被设置为true,则此后,
一旦线程调用了wait、jion、sleep方法中的一种,立马抛出一个InterruptedException,且中断标志被清除,
重新设置为false。
join() 等待 join方法的实现依赖于wait方法,所以join方法会释放锁。
wait(),sleep(),yield(),join()区别
wait()方法在Object中定义的,其他只有Thread中有。
wait(),join()会释放锁,sleep(),yield()不会。
wait()可以由参数,join()没有。
sleep()可以有参数,yield()没有。
Thread中的stop()和suspend()方法,由于固有的不安全性,已经建议不再使用!
(1) stop(), suspend(), resume() 和Runtime.runFinalizersOnExit() ,但这些方法已经被废弃。