sleep()
当线程调用这个方法时,会交出CPU时间,让其他线程去执行,但是这个方法并不会释放锁,运行下面的例子就可以了解这个原理:
public class Test {
private int i = 10;
private Object object = new Object();
public static void main(String[] args) throws IOException {
Test test = new Test();
MyThread thread1 = test.new MyThread();
MyThread thread2 = test.new MyThread();
thread1.start();
thread2.start();
}
class MyThread extends Thread{
@Override
public void run() {
synchronized (object) {
i++;
System.out.println("i:"+i);
try {
System.out.println("线程"+Thread.currentThread().getName()+"进入睡眠状态");
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println("线程"+Thread.currentThread().getName()+"睡眠结束");
i++;
System.out.println("i:"+i);
}
}
}
}
调用sleep()方法的线程将会进入阻塞状态。
yield()
yield()方法与sleep()方法基本是一样的,不同的是以下两点:
- yield方法不能控制具体交出CPU的时间,而且只有与它优先级相同的线程才有获得CPU时间的机会。
- yield方法不会进入阻塞状态,而是直接进入就绪状态,只要获得CPU时间就可以执行
join()
join方法有如下三个重载方法:
join()
join(long millis) //参数为毫秒
join(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒
如果在main线程中调用thread.join()方法,那么main方法会等待thread线程执行完毕或者等待一定时间。如果调用的是无参join方法,则等待thread线程执行完毕;如果是调用的是制定了时间参数的join方法,则等待一定的时间之后,main线程恢复执行。
下面是一个join方法的例子:
public class Test {
public static void main(String[] args) throws IOException {
System.out.println("进入线程"+Thread.currentThread().getName());
Test test = new Test();
MyThread thread1 = test.new MyThread();
thread1.start();
try {
System.out.println("线程"+Thread.currentThread().getName()+"等待");
thread1.join();
System.out.println("线程"+Thread.currentThread().getName()+"继续执行");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class MyThread extends Thread{
@Override
public void run() {
System.out.println("进入线程"+Thread.currentThread().getName());
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println("线程"+Thread.currentThread().getName()+"执行完毕");
}
}
}
join方法会让线程进入阻塞状态同时释放对象的锁。
interrupt()
中断一个处于阻塞状态的线程,切记:它不能中断一个正在运行中的程序。
下面这个例子是中断阻塞中的线程:
public class Test {
public static void main(String[] args) throws IOException {
Test test = new Test();
MyThread thread = test.new MyThread();
thread.start();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
}
thread.interrupt();
}
class MyThread extends Thread{
@Override
public void run() {
try {
System.out.println("进入睡眠状态");
Thread.currentThread().sleep(10000);
System.out.println("睡眠完毕");
} catch (InterruptedException e) {
System.out.println("得到中断异常");
}
System.out.println("run方法执行完毕");
}
}
}
下面这个例子证明了无法中断正在运行中的线程:
public class Test {
public static void main(String[] args) throws IOException {
Test test = new Test();
MyThread thread = test.new MyThread();
thread.start();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
}
thread.interrupt();
}
class MyThread extends Thread{
@Override
public void run() {
int i = 0;
while(i<Integer.MAX_VALUE){
System.out.println(i+" while循环");
i++;
}
}
}
}
线程的生命周期