wait(),notify(),notifyAll()

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调度的可能性越大

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值