java 为线程操作提供了一些 API。比如,如果新建并且启动县农村,如何终止线程等。当然,因为并行操作要比串行操作复杂得多,于是,围绕着这些常用接口,可能有些比较隐晦的坑等着你去踩。
java有6种线程状态:
- 初始(NEW)
- 运行(RUNNABLE)
- 阻塞(BLOCKED)
- 等待(WAITING)
- 超时等待(TIMED_WAITING)
- 终止(TERMINATED)
在给定的时间点,线程只能处于一种状态。 这些状态是不反映任何操作系统线程状态的虚拟机状态。
终止线程
使用stop方法强制线程停止,不安全,已废弃!
stop方法:
@Deprecated
public final void stop() {}
除非你很清楚自己在做什么,否则不要随便使用你 stop() 方法来停止一个线程。
如果需要停止一个线程,可以增加一个方法自行决定何时退出。
public class ChangeObjectThread extends Thread {
volatile boolean stopme = false;
public void stopMe() {
stopme = true;
}
@Override
public void run() {
while (true) {
if (stopme) {
System.out.println("终止线程");
break;
}
}
}
}
线程中断
调用Thread类的 interrupted()
方法,其本质只是设置该线程的中断标志,将中断标志设置为true,并根据线程状态决定是否抛出异常。因此,通过 interrupted()
方法真正实现线程的中断原理是 :开发人员根据中断标志的具体值来决定如何退出线程。
interrupt()方法
public void interrupt() {}
等待(wait)
obj.wait()
,当前线程调用对象的 wait()
方法,当前线程释放对象锁,进入等待队列。依靠notify()/notifyAll()
唤醒或者wait(long timeout)
timeout 时间到自动唤醒
public final void wait() throws InterruptedException {}
public final native void wait(long timeout) throws InterruptedException;
通知(notify)
obj.notify()
唤醒在此对象监视器上等待的单个线程,选择是任意性的。notifyAll()
唤醒在此对象监视器上等待的所有线程
public final native void notify();
public final native void notifyAll();
挂起(suspend)和继续执行(resume)线程
线程thread在运行到suspend()
之后被强制挂起,暂停运行,直到主线程调用thread.resume()
方法时才被重新唤醒。
使用suspend()
方法挂起线程回导致线程在暂停的同时,不释放任何锁资源。
如果需要一个比较可靠的 suspend()
方法,可以利用 wait()
方法和 notify()
方法,在应用层面实现 suspend()
方法和 resumme()
方法
等待线程结束(join)
等待线程终止,指的是:主线程中调用该方法,就会让调用该方法的线程先执行,等执行结束后,再回到主线程继续执行。(即等待,调用 join()
方法的线程执行完毕后,再执行)
join()方法:
public final void join() throws InterruptedException {
//join带参数指的是等待的超时时间,为0代表永久等待
join(0);
}
谦让(yield)
线程让步,指的是让当前线程暂停执行,并执行其他线程。
public static native void yield();
与sleep()的区别在于:
- yield()方法无法控制具体交出CPU的时间
- yield()方法只能让拥有相同优先级的线程获得CPU执行的机会
- yield()方法让当前线程进入Runnable状态