学习目标:掌握线程的休眠、中断、加入等操作方法。
线程的休眠
线程的休眠就是把当前正在运行的线程挂起一段时间(时间值由参数传入),挂起时间到期后,JVM会在适当的时间再次唤醒该线程。
Thread类的sleep()方法可以让当前线程休眠,sleep()方法说明如下:
sleep (long millis) throws InterruptedException
该方法用于在指定的millis毫秒内让当前正在执行的线程休眠(暂停执行),该方法的执行可能会抛出InterruptedException异常,因此需要将sleep()方法的调用放在try-catch块中。
案例3:建立ThreadSleep类,并在run()方法中编写线程功能代码。
在thread包下新建ThreadSleep类。代码如下:
package thread;
public class ThreadSleep extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for (int i = 0; i < 100; i++) {
System.out.println("MyRunner:" + i);
try {
System.out.println(Thread.currentThread().getName() + "休眠0.5秒!");
//自身线程挂起500毫秒
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
ThreadSleep类在每次循环都会调用Thread类的sleep方法将自身线程挂起500毫秒,然后再继续执行。
在thread包下新建ThreadSleepTest测试类,启动ThreadSleep线程。代码如下:
package thread;
public class ThreadSleepTest {
public static void main(String[] args) {
// 实例化MyThread对象
ThreadSleep thread = new ThreadSleep();
// 调用Thread类的strat()方法启动线程
thread.start();
try {
//主线程挂起1000毫秒
System.out.println(Thread.currentThread().getName()+ "休眠1秒!");
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在ThreadSleepTest类主线程启动子线程后,应用Thread类的sleep方法将主线程挂起1000毫秒,因为sleep方法抛出InterruptedException异常,因此调用sleep方法时,需要包含在try-cahtch语句,用于捕获sleep方法可能抛出的异常。
程序执行结果如下图所示:

线程的中断
线程的中断不是停止线程的运行,而是在线程中设置中断状态,被中断的线程需要响应和处理中断状态。
Thread类定义了三个与中断相关的方法,分别说明如下:
● void interrupt()
该方法用于中断当前线程,设置当前线程为中断状态。
● boolean interrupted()
该方法用于判断当前线程是否处于中断状态,如果处于中断状态返回true,并清除线程的中断状态标记。
● boolean interrupted()
该方法用于判断当前线程是否处于中断状态,如果处于中断状态返回true,该方法不会清除线程的中断状态标记。
案例4:建立ThreadInterrup类,并在run()方法中编写线程功能代码。
在thread包下新建ThreadInterrup类。代码如下:
package thread;
public class ThreadInterrup extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for( int i = 0; i<100; i++ ) {
// 响应中断
if (Thread.currentThread().isInterrupted()) {
System.out.println("ThreadInterrup线程被中断,程序退出。");
return;
}
System.out.println("ThreadInterrup:" + i);
}
}
}
ThreadInterrup类对线程的中断状态进行了响应处理,在for循环中调用Thread类的isInterrupted()方法判断线程是否处于中断状态,如果被设置为中断状态则退出程序。
在thread包下新建ThreadInterrupTest测试类,启动ThreadInterrup线程,并调用interrupt()方法中断线程。代码如下:
package thread;
public class ThreadInterrupTest {
public static void main(String[] args) {
// 实例化MyThread对象
ThreadInterrup thread = new ThreadInterrup();
// 调用Thread类的strat()方法启动线程
thread.start();
// 中断当前线程
thread.interrupt();
}
}
在ThreadInterrupTest类主线程启动子线程后,应用Thread类的interrupt()方法中断子线程,因为子线程内部对线程中断状态进行了响应处理,因此子线程结束运行。
程序执行结果如下图所示:

当线程内部不响应中断状态时,调用Thread类的interrupt()方法对线程没有任何影响。
线程的加入
线程的加入是指在当前线程中执行另外一个线程。例如A线程在执行过程中需要先执行B线程,等待B线程执行完毕后,A线程再继续执行。在这种情况下,就可以使用Thread类的join()方法来完成。
下面是Thread类线程加入相关的常用方法,分别说明如下:
● void join()
该方法用于将当前线程加入到另外一个线程,另外一个线程会等待该线程执行完毕再继续执行。
● void join(long millis)
该方法用于将当前线程加入到另外一个线程,另外一个线程会等待该线程执行millis毫秒后再执行,如果当前线程millis毫秒后没有结束,两个线程会并发执行。
案例5:建立ThreadA类和ThreadB类,在ThreadA类加入ThreadB类线程。
在thread包下新建ThreadA类。代码如下:
package thread;
public class ThreadA extends Thread{
Thread threadB = null;
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
// 在线程中执行的代码
for( int i = 0; i<100; i++ ) {
if( i == 10)
{
// 调用threadB的join方法,执行threadB线程
if( threadB != null )
{
try {
threadB.start();
threadB.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.println("ThreadA:" + i);
}
}
public Thread getThreadB() {
return threadB;
}
public void setThreadB(Thread threadB) {
this.threadB = threadB;
}
}
ThreadA类内部定义了Thread类型的变量,用于存储ThreadB的实例对象引用。在ThreadA类的run()方法调用启动ThreadB线程,并调用ThreadB的join()方法,等待ThreadB线程执行完毕。
在thread包下新建ThreadB类。代码如下:
package thread;
public class ThreadB extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
try {
System.out.println("线程B启动");
Thread.sleep(500);
System.out.println("线程B结束");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ThreadB线程休眠500毫秒后结束。
在thread包下新建ThreadJoinTest类。代码如下:
package thread;
public class ThreadJoinTest {
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
ThreadB threadB = new ThreadB();
threadA.setThreadB(threadB);
threadA.start();
}
}
ThreadJoinTest程序分别实例化ThreadA和ThreadB对象,调用ThreadA的setThreadB()方法设置ThreadA的threadB变量,并启动ThreadA线程。