Thread类中的方法:join()、sleep()、yield() wait()之间的区别

参考内容:https://blog.csdn.net/xzp_12345/article/details/81129735 

               https://www.jianshu.com/p/19f861ab749e

     join()方法会释放

1. Join()方法
Thread的非静态方法join()让一个线程等待另外一个线程完成才继续执行。如果线程A执行体中调用B线程的join()方法,则A线程将会被阻塞,直到B线程执行完为止,A才能得以继续执行。

如下图:

而且一定要理解“继续执行”的含义。比如有下面的三个线程:

其中thread2线程执行了join()方法。也就是必须等thread2执行结束之后才能继续往下执行thread3。但是,在执行thread2的过程中可以执行thread1(往前执行线程)。这就是“继续执行”的含义。

2. Sleep() 方法:不会释放锁
Sleep——让当前正在执行的线程先暂停一定的时间,并进入阻塞状态。在其睡眠的时间段内,该线程由于不是处于就绪状态,因此不会得到执行的机会。即使此时系统中没有任何其他可执行的线程,处于sleep()中的线程也不会执行。因此sleep()方法常用来暂停线程的执行。当sleep()结束后,然后转入到 Runnable(就绪状态),这样才能够得到执行的机会。

3.Yield()方法:线程让步  不会释放锁
让一个线程执行了yield()方法后,就会进入Runnable(就绪状态),【不同于sleep()和join()方法,因为这两个方法是使线程进入阻塞状态】。除此之外,yield()方法还与线程优先级有关,当某个线程调用yield()方法时,就会从运行状态转换到就绪状态后,CPU从就绪状态线程队列中只会选择与该线程优先级相同或者更高优先级的线程去执行。

yield()方法对应了如下操作;先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把CPU的占有权交给次线程,否则继续运行原来的线程,所以yield()方法称为“退让”,它把运行机会让给了同等级的其他线程。

4.wait()和notify(),notifyAll()

wait()和notify()因为会对对象的“锁标志”进行操作,所以他们必需在Synchronized函数或者 synchronized block 中进行调用。如果在non-synchronized 函数或 non-synchronized block 中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。。

import java.util.concurrent.TimeUnit;

/**
 * Created by j_zhan on 2016/7/6.
 */
public class WaitNotify {
    static boolean flag = true;
    static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread A = new Thread(new Wait(), "wait thread");
        A.start();
        TimeUnit.SECONDS.sleep(2);
        Thread B = new Thread(new Notify(), "notify thread");
        B.start();
    }

    static class Wait implements Runnable {
        @Override
        public void run() {
            synchronized (lock) {
                while (flag) {
                    try {
                        System.out.println(Thread.currentThread() + " flag is true");
                        lock.wait();
                    } catch (InterruptedException e) {

                    }
                }
                System.out.println(Thread.currentThread() + " flag is false");
            }
        }
    }

    static class Notify implements Runnable {
        @Override
        public void run() {
            synchronized (lock) {
                flag = false;
                lock.notifyAll();
                try {
                    TimeUnit.SECONDS.sleep(7);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  1. 使用wait()、notify()和notifyAll()时需要先对调用对象加锁,调用wait()方法后会释放锁。
  2. 调用wait()方法之后,线程状态由RUNNING变为WAITING,并将当前线程放置到对象的等待队列中。
  3. notify()或notifyAll()方法调用后,等待线程不会立刻从wait()中返回,需要等该线程释放锁之后,才有机会获取锁之后从wait()返回。
  4. notify()方法将等待队列中的一个等待线程从等待队列中移动到同步队列中;notifyAll()方法则是把等待队列中的所有线程都移动到同步队列中;被移动的线程状态从WAITING变为BLOCKED。
  5. 从wait()方法返回的前提是,改线程获得了调用对象的锁。

 

 

 

 

你可能感兴趣的:(线程)