在上一篇文章中我们介绍了线程创建和线程状态的相关知识 :线程的基本状态,如何创建线程,以及线程的生命周期。 我们已经知道,进程和线程都是一个时间段的描述,是CPU工作时间段的描述。进程是程序的执行过程,线程是计算机系统的最小执行单元,是进程中的一个个小任务。如下图,形象生动地表述了进程和线程的关系。
线程的创建有两种方式,继承Thread类或者实现Runnable接口。当我们创建好一个线程之后,线程处于新建状态。在线程的整个生命周期中,包括新建,就绪,运行,阻塞和死亡等。利用已有知识我们已经可以写出如何利用多线程处理大量任务这样简单的程序。但是当应用场景复杂时,我们还需要从管理控制入手,更好的操纵多线程,包括:对线程的等待、守护线程、线程的睡眠、线程的突然停止、线程的让步、线程的优先级等。
当我们开始应用线程来解决工作中的相关问题时,
(1)如何让一个线程按照我们的设想来操作复杂情形,如线程的等待、守护线程、线程的睡眠等。
(2)多个线程被cpu调用时,如何线程不同线程的调用顺序呢?
(2)线程的特点在于资源共享,当多个线程操作同一数据会使得数据混乱,那么,应该如何处理这种情况呢?
(一)线程的常用方法体介绍
-
线程的等待和唤醒
在Object.java中,定义了wait(), notify()和notifyAll()等方法,用来实现线程的等待和唤醒。
wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。
notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程;
notify()是唤醒单个线程—————— 唤醒在此对象监视器上等待的单个线程。
notifyAll()是唤醒所有的线程————-- 唤醒在此对象监视器上等待的所有线程。
wait() -- 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被唤醒(进入“就绪状态”)。
wait(long timeout) -- 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量”,当前线程被唤醒(进入“就绪状态”)。
wait(long timeout, int nanos) -- 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量”,当前线程被唤醒(进入“就绪状态”)。
package myTest;
public class TestDemo {
//定义三个线程t1,t2,t3,同时还有一个主线程mian();应该注意的是
//当启用start()方法时,程序执行ThreadA中的run方法,最重要的
//是wait()方法的作用。
private static Object obj = new Object();
public static void main(String[] args) {
ThreadA t1 = new ThreadA("t1");
ThreadA t2 = new ThreadA("t2");
ThreadA t3 = new ThreadA("t3");
t1.start();
t2.start();
t3.start();
try {
System.out.println(Thread.currentThread().getName()+" sleep(3000)");
Thread.sleep(