\( ̄︶ ̄)/

        wait() 方法和 sleep() 方法都可以使线程挂起,起到的效果看似相同,但其实二者之间存在许多差异。

相同点:

(1) 都可以使线程在程序的调用处阻塞指定的毫秒数,然后回到可运行状态。

(2) wait() 和 sleep() 都可以通过 interrupt() 方法打断线程的暂停状态(不建议使用该方法)。

注:对线程对象调用 interrupt() 方法时,如果该线程对象处于 wait / sleep / join 状态时,该线程会立刻抛出 InterruptedException,在catch() {} 中直接 return 即可安全地结束线程;如果该线程正在执行的是普通代码,那么该线程不会抛出 InterruptedException。

不同点:

(1) sleep() 是Thread类的static(静态)的方法。( yield() 同样为静态方法)。
wait() 是非静态方法,需要由线程对象来调用。( 非静态方法还有 join(), notify(), notifyAll()等 )。

(2) sleep()睡眠时,不会释放对象锁,有造成死锁的可能;
wait() 等待时,释放对象锁,其他线程可以访问。

(3) wait()、notify() 和 notifyAll() 只能在同步控制方法或者同步控制块里面使用,而 sleep() 可以在任何地方使用。

(4) sleep() 必须捕获异常,而wait(),notify() 和 notifyAll() 不需要捕获异常

在 sleep() 休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。
wait() 使用 notify() 或者 notifyAll() 或者指定睡眠时间来唤醒当前等待池中的线程。wiat() 必须放在synchronized block中,否则会在program runtime时抛出“java.lang.IllegalMonitorStateException”异常。

线程的优先级

优先级越高代表被cpu执行的概率越大(1到10),一般1、5与10的差距是最大的。 因为是静态常量,因此需要加上类名 。

字段摘要:Thread.MAX_PRIORITY,线程可以具有的最高优先级;Thread.MIN_PRIORITY,线程可以具有的最低优先级;Thread.NORM_PRIORITY,分配给线程的默认优先级,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyThread implements Runnable{
public void run(){
for (int x=0;x<50;x++){
System.out.println(Thread.currentThread().getName()+"......"+x);
}
}
}

public class JoinDemo {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
Thread t1 = new Thread(mt);
Thread t2 = new Thread(mt);
t1.start();
//临时加入一个线程运算时可以使用join方法
t1.join();//t1线程要申请加入进来运行,主线程等待t1终止之后再执行,即此时主线程处于冻结状态,是可以使用interrupt方法强制恢复回来的
t2.start();
t2.setPriority(Thread.MAX_PRIORITY);//设置t2为最优先执行
//t1.join();//t1线程申请加入;此时开启的线程是t1与t2,即t1与t2互相争夺执行权,但是主线程仅仅与t1线程相关联,在线程t1执行结束后主线程开始执行
for (int x=0;x<50;x++){
System.out.println(Thread.currentThread().getName()+"......"+x);
}
}
}

Thread.yield() 方法

yield() 方法:暂停当前正在执行的线程对象,并执行其他线程。
yield() 应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。
因此,使用 yield() 的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证 yield() 达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。