Java多线程

java 多线程编程-线程方法join、wait、sleep

2020-02-13  本文已影响0人  尹楷楷

join()

1、在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行

2、带时间参数的join:
如果A线程中调用B线程的join(10),则表示A线程会等待B线程执行10毫秒,10毫秒过后,A、B线程并发执行。需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()
可以看看join的源码,join()最终调用的是join(0)

image.png

3、Join 是使用wait-nodify机制实现的


image.png

4、使用示例

使用join()方式实现 main线程等待所有子线程执行完毕

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


        List<Thread> list = new ArrayList<>();
        for (int i = 0; i <10 ; i++) {
            int finalI = i;
            Thread thread = new Thread(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    Thread.sleep(1000*(finalI +1));
                    System.out.println(Thread.currentThread().getName()+"执行!");

                }
            },"thread-"+(i +1));

            thread.start();
            list.add(thread);

        }

        for (Thread thread : list) {
            thread.join();
        }
        System.out.println("所有线程都执行完毕。。。");


    }

wait()

可以看看我的这篇文章<<java 线程编程-wait-notify机制>>
https://www.jianshu.com/p/36b57330531c

需要注意的是:
wait() 方法的调用会释放出当前线程所持有的监视器锁

sleep()

带参数 sleep(n)

假设现在是 2019-10-1 12:00:00.000,如果我调用一下 Thread.Sleep(1000) ,在 2019-10-1 12:00:01.000 的时候,这个线程会不会被唤醒?

结果不确定

因为sleep(1000)只是告诉操作系统:在未来的1秒内我不想再参与到CPU竞争。那么1000毫秒过去之后

说明sleep结束之后线程可能不会立即继续执行,sleep(n) 方法会导致线程状改变:


image.png

sleep(0)的意义

在线程中,调用sleep(0)可以释放cpu时间,让线程马上从等待队列中出来到就绪队列,sleep(0)释放当前线程所剩余的时间片(如果有剩余的话),这样可以让操作系统切换其他线程来执行,提升效率。

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

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    while (true) {
                        Thread.sleep(0);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();

        while (true){
            System.out.println(thread.getState());
        }

    }

运行结果:
TIMED_WAITING
TIMED_WAITING
RUNNABLE
TIMED_WAITING
TIMED_WAITING

image.png

yield()

这是一个静态方法,一旦执行,它会使当前线程让出CPU。另外,让出的时间片只会分配给当前线程相同优先级的线程。但如果系统中没有相同优先级的线程,那么本线程又会重新占用cup继续运行(让出的CPU并不是代表当前线程不再运行了。如果在下一次竞争中,又获得了CPU时间片当前线程依然会继续运行)

 public static void main(String[] args)   {

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    Thread.yield();
                }
            }
        });
        thread.start();

        while (true){
            System.out.println(thread.getState());
        }

    }

执行结果
RUNNABLE
RUNNABLE
RUNNABLE
RUNNABLE
RUNNABLE
RUNNABLE

image.png

wait()和sleep()的区别

两者的相同点
wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态、将线程中断标志位设为true,从而使线程立刻抛出InterruptedException。如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。

上一篇下一篇

猜你喜欢

热点阅读