线程等待与唤醒

线程等待与唤醒

标签: 多线程


基本方法简介

所有的等待和唤醒线程,都是针对某个具体对象实例的.

API接口说明
wait()让当前线程进入等待(阻塞)状态,直到其他线程调用此对象的notify()或notifyAll()来唤醒,之后该线程进入就绪状态.
wait(long timeout)让当前线程进入阻塞状态,直到其他线程唤醒此线程或者超过指定时间,之后该线程进入就绪状态
wait(long timeout,int nanos)让当前线程进入阻塞状态,直到其他线程唤醒此线程或者超过指定时间或者超过某个实际时间,之后该线程进入就绪状态
notify()唤醒该对象上的指定单个线程
notifyAll()唤醒该对象上的所有线程

wait() and notify() demo

package cn.kkcoder.thread;

public class WaitAndNotify {

    public static void main(String[] args) throws InterruptedException {

        notifyThread t = new notifyThread("t1");

        synchronized(t) {

            System.out.println(Thread.currentThread().getName() + " .start()");
            t.start();

            System.out.println(Thread.currentThread().getName() + "  .wait()");
            t.wait();

            System.out.println(Thread.currentThread().getName() + " .结束");
        }

    }

}
class notifyThread extends Thread{

    public notifyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        synchronized(this) {
            System.out.println(Thread.currentThread().getName() + "  call notify()");
            notify();
        }

    }

}
控制台:
main .start()
main  .wait()
t1  call notify()
main .结束

总结: wait() 方法是指让当前线程等待,并释放对象锁, 而此时的当前线程是 主线程,因为主线程获取了对象 t 的锁,t.start()之后,新建线程t1,并进入就绪状态,但是此时锁在 main 线程中,所以t1的run方法不执行,当t.wait()之后,当前线程(即主线程)进入等待(阻塞)状态,并释放t线程锁,于是执行run方法,唤醒等待的main线程,并且线程t1释放锁进入死亡状态.main线程继续执行.


tips:wait()指当先线程进入等待状态.

wait() and notifyAll() demo

package cn.kkcoder.thread;

public class NotifyAll {

    static Object obj = new Object();

    public static void main(String[] args) {

        NotifyAllClass t1 = new NotifyAllClass("t1");
        NotifyAllClass t2 = new NotifyAllClass("t2");
        NotifyAllClass t3 = new NotifyAllClass("t3");

        t1.start();
        t2.start();
        t3.start();

        try {
            System.out.println(Thread.currentThread().getName() + " sleep 3000 ms");
            Thread.currentThread().sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        synchronized (obj) {
            System.out.println(Thread.currentThread().getName() + " 唤醒所有线程");
            obj.notifyAll();
        }

    }


    static class NotifyAllClass extends Thread{

        public NotifyAllClass(String name) {
            super(name);
        }

        @Override
        public void run() {

            synchronized (obj) {
                try {
                    System.out.println(Thread.currentThread().getName() + " 执行 wait ");
                    obj.wait();
                    System.out.println(Thread.currentThread().getName() + "继续 执行");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

控制台:
main sleep 3000 ms
t1 执行 wait 
t3 执行 wait 
t2 执行 wait 
main 唤醒所有线程
t2继续 执行
t3继续 执行
t1继续 执行

t1,t2,t3和主线程 分别执行, t1,t2,t3线程分别 持有ojb对象,并执行了等待,并释放各自的锁,都进入阻塞状态,主线程(mian)线程 sleep 之后,获取obj对象的锁,执行notifyAll,唤醒所有线程.t1,t2,t3之后并执行结束,释放obj的同步锁,之后被唤醒并继续执行.


最后: notify() 和 wait() 等方法依赖于 同步锁 ,同步锁依赖于 对象,所以,这些方法也是依赖于 对象 的.


yield() demo

package cn.kkcoder.thread;

public class YieldTet {

    static Object obj = new Object();

    public static void main(String[] args) {
        TestYield t1 = new TestYield("t1");
        TestYield t2 = new TestYield("t2");

        t1.start();
        t2.start();
    }

    static class TestYield extends Thread{
        public TestYield(String name) {
            super(name);
        }

        @Override
        public void run() {

            synchronized(obj) {
                for(int i=0;i<=5;i++) {

                    System.out.println(Thread.currentThread().getName() + " i = " + i);

                    if(i%3==0) {
                        System.out.println(Thread.currentThread().getName() + " 执行yield");
                        Thread.yield();
                    }
                }
            }
        }
    }
}
控制台:
t1 i = 0
t1 执行yield
t1 i = 1
t1 i = 2
t1 i = 3
t1 执行yield
t1 i = 4
t1 i = 5
t2 i = 0
t2 执行yield
t2 i = 1
t2 i = 2
t2 i = 3
t2 执行yield
t2 i = 4
t2 i = 5

yield() 方法会进行让步,但不会释放同步锁.即yield会把该线程从运行状态,转换到 就绪状态.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值