1.obj.wait()
该方法会先判断当前线程有没有obj对象的锁,没有则会报java.lang.IllegalMonitorStateException异常,有则释放该obj对象锁,将线程挂起,进入阻塞状态
wait()方法什么时候结束阻塞呢?
①当前运行的线程调用obj.notify():随机唤醒其中一个阻塞线程,obj.notifyAll():唤醒所有阻塞线程,唤醒的是那些因为调用obj.wait()而阻塞的线程。
public class Test2 {
static Thread threadA;
static Thread threadB;
static Thread threadC;
private static C c;
public static void main(String[] args) throws InterruptedException {
threadA = new Thread(new A());
threadB = new Thread(new B());
c = new C();
threadC = new Thread(c);
threadC.start();
Thread.sleep(200);
threadB.start();
Thread.sleep(200);
threadA.start();
}
static class A implements Runnable{
@Override
public void run() {
synchronized (c){//同步c,获取c对象锁
try {
System.out.println("A开始等待B!");
threadB.join();
System.out.println("A结束等待B,A开始睡眠!");
c.notifyAll();//释放c对象锁,会唤醒那些调用c.wait()的线程
System.out.println("A结束睡眠!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class B implements Runnable{
@Override
public void run() {
try {
System.out.println("B开始睡眠!");
Thread.sleep(3000);
System.out.println("B结束睡眠!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class C implements Runnable{
@Override
public void run() {
//this即使当前的C c对象
synchronized (this){
try {
System.out.println("C开始等待!");
wait();//相当于c.wait(),因此可以被A线程的c.notifyAll()唤醒
System.out.println("C结束等待!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
②使用的是wait(long time),则阻塞time毫秒后进入就绪状态
③当一个线程thread执行完后,会调用自身的notifyAll()方法,即可以唤醒那些调用了thread.wait()的线程,如Thread中的join方法:
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);//thread.wait(0),这个阻塞0毫秒就会结束阻塞
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
//当线程thread运行完后就会调用自身的notifyAll()方法,因此调用了thread.wait()的当前线程就会被唤醒,进入就绪状态
wait(delay);//thread.wait(delay),
now = System.currentTimeMillis() - base;
}
}
}
当线程thread里调用的obj.wait(),放弃CPU资源,状态由Runnable -> Waiting,线程从就绪队列移到obj指向的等待集(wait sets),开始阻塞,直到有线程唤醒它
当其他线程调用obj.notify后,会把obj指向的等待集(wait sets)上的任意一个线程移到就绪队列,状态变为Waiting -> Runnable,notifyAll()会唤醒等待集中所有线程,正是因为wait(),notify(),notifyAll()会修改obj指向的等待集,因此为保证原子性,必须给该obj上锁。
2.Thread.holdsLock(Object obj)
当前线程有obj对象锁,则return true,否则return false (使用对象调用静态方法实际上是类调用)
3.Thread.yield()
当前线程让出CPU,并进入就绪状态,等待CPU的下一次调度
4.thread.setPriority(1~10)
设置优先级,优先级越大,则被CPU调度的可能性越大