java多线程之wait,join,yield

java多线程同步一般用的是synchronized关键字,对其他几个函数wait,join,yield用的不多,尤其是join,yield总是很模糊,现在理一理加深印象。

1、wait

wait用于进入对象锁相关的等待池中,执行wait后会释放对象锁和CPU资源,此时其他线程可以访问获取对象锁了。

wait()经常与notify()(唤醒等待池中的任意一个wait对象),notifyAll(唤醒等待池中的所有wait对象)在一起使用。wait(long timeout)和wait(long timeout, int nanos)既可以用notify()、notifyAll唤醒也可以在超时时间后自动唤醒。值得注意的是wait和notify、notifyAll都必须在synchronized代码块中(The current thread must own this object's monitor)。

private static Object mLockObject=new Object();
    private static void waitTest() {
        System.out.println("主线程运行");
        Thread thread=new waitThread();
        thread.start();
        long startTime=System.currentTimeMillis();
        synchronized (mLockObject){
            System.out.println("主线程等待");
            try {
                mLockObject.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("主线程继续执行,等待耗时:"+(System.currentTimeMillis()-startTime));
    }

    static class waitThread extends Thread{
        @Override
        public void run() {
            synchronized (mLockObject){
                try {
                    System.out.println("子线程开始sleep");
                    Thread.sleep(3000);
                    mLockObject.notifyAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

日志打印如下,可以看出子线程执行notifyAll后主线程才会被唤醒并继续执行。

主线程运行
主线程等待
子线程开始sleep
主线程继续执行,等待耗时:3002

2、join

join用于当前线程等待目标线程完成之后再继续执行

    private static void joinTest() {
        System.out.println("主线程运行");
        Thread thread=new joinThread();
        thread.start();
        long startTime=System.currentTimeMillis();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("主线程继续执行,join耗时:"+(System.currentTimeMillis()-startTime));
    }
    static class joinThread extends Thread{
        @Override
        public void run() {
            try {
                System.out.println("子线程开始sleep");
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

日志打印如下,可以看出子线程执行完后,主线程才会继续执行。

主线程运行
子线程开始sleep
主线程继续执行,join耗时:3003

3、yield

yield用于主动让出执行时间给其他已就绪的线程,当前线程从运行状态转为就绪状态,其他线程是否能够优先执行要看各个线程的状态了。

    private static void yieldTest() {
        yieldThread mThread1=new yieldThread("thread-1");
        yieldThread mThread2=new yieldThread("thread-2");
        mThread1.start();
        mThread2.start();
    }
    static class yieldThread extends Thread{
        public yieldThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.printf("%s------>%d\n",this.getName(),i);
                if (i==2) {
                    Thread.yield();
                }
            }
        }
    }

log显示mThread1执行到i=2时让出了执行时间,mThread2开始执行,当mThread2执行i=2时又交给mThread1继续执行

thread-1------>0
thread-1------>1
thread-1------>2
thread-2------>0
thread-2------>1
thread-2------>2
thread-2------>3
thread-2------>4
thread-1------>3
thread-1------>4

猜你喜欢

转载自blog.csdn.net/u013795543/article/details/104127246