面试题:线程A打印1-10数字,打印到第5个数字时,通知线程B

关于线程通信这块,一直处于一知半解的状态,没有进行系统全面的学习,看了前辈的博客后,按照自己的理解手敲了一遍,写篇博客记录一下,方便自己以后查阅复习。

  1. park/unpark
  2. volatile关键字
  3. synchronized + wait/notify
  4. countdownlatch
  5. condition + await/signal

1 park/unpark

package com.example.demo.demo;

import java.util.concurrent.locks.LockSupport;

/**
 * @version V1.0
 * @ClassName: ABDemo
 * @Description: TODO
 * @author: guoyiying
 * @date 2020/1/7 9:28
 */
public class ABDemo {

    public static void main(String[] args) {
        Thread b = new Thread(new Runnable() {
            @Override
            public void run() {
                LockSupport.park();
                System.out.println("i am thread b, i am still alive.");
            }
        });

        Thread a = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=1; i<11; i++){
                    System.out.println(i);
                    if(i==5){
                        LockSupport.unpark(b);
                    }
                }
            }
        });

        a.start();
        b.start();
    }
}

2 volatile关键字

package com.example.demo.demo;

/**
 * @version V1.0
 * @ClassName: wzl
 * @Description: TODO
 * @author: guoyiying
 * @date 2020/1/7 9:28
 */
public class ABDemo {

    private volatile static boolean flag = false;

    public static void main(String[] args) {

        Thread a = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=1; i<11; i++){
                    System.out.println(i);
                    if(i==5){
                        flag = true;
                    }
                }
            }
        });

        Thread b = new Thread(new Runnable() {
            @Override
            public void run() {
                while(!flag){}
                System.out.println("i am thread b, i am still alive.");
            }
        });

        a.start();
        b.start();
    }
}

3 synchronized + wait/notify

注意:

  • wait/notify关键字需搭配synchronized关键字食用
  • 需先调用wait,再调用notify,否则会导致死锁,所以先启动线程b,再启动线程a
package com.example.demo.demo;

/** 
 * @version V1.0
 * @ClassName:        
 * @Description: TODO
 * @author: guoyiying
 * @date 2020/1/7 10:53
*/
public class ABDemo {

    private static Object object = new Object();

    public static void main(String[] args) {
        Thread a = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object){
                    for(int i=1; i<11; i++){
                        System.out.println(i);
                        if(i==5){
                            object.notify();
                        }
                    }
                }
            }
        });

        Thread b = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object){
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("i am thread b, i am still alive.");
                }
            }
        });

        b.start();
        a.start();
    }
}

4 countdownlatch

每调用一次countDown方法,计数器-1,减为0时,所有调用await的代码将被唤醒。

package com.example.demo.demo;

import java.util.concurrent.CountDownLatch;

/** 
 * @version V1.0
 * @ClassName:        
 * @Description: TODO
 * @author: guoyiying
 * @date 2020/1/7 10:57
*/
public class ABDemo {

    private static CountDownLatch countDownLatch = new CountDownLatch(1);

    public static void main(String[] args) {
        Thread a = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=1; i<11; i++){
                    System.out.println(i);
                    if(i==5){
                        countDownLatch.countDown();
                    }
                }
            }
        });

        Thread b = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    countDownLatch.await();
                    System.out.println("i am thread b, i am still alive.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        a.start();
        b.start();
    }
}

5 condition + await/signal

注意:

  • 同wait/notify,调用顺序可能会导致死锁
  • 网上查了一下,说是await搭配signalAll可以避免死锁,亲测之后,发现还是会有死锁的出现
  • 关于这点,还在学习当中,欢迎各位看官留言批评指正
package com.example.demo.demo;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/** 
 * @version V1.0
 * @ClassName:        
 * @Description: TODO
 * @author: guoyiying
 * @date 2020/1/7 11:04
*/
public class ABDemo {

    private static Lock lock = new ReentrantLock();
    private static Condition condition = lock.newCondition();

    public static void main(String[] args) {
        Thread a = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    lock.lock();
                    for(int i=1; i<11; i++){
                        System.out.println(i);
                        if(i==5){
                            condition.signalAll();
                        }
                    }
                }finally {
                    lock.unlock();
                }
            }
        });

        Thread b = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                lock.lock();
                try {

                    condition.await();
                    System.out.println("i am thread b, i am still alive.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }}
                finally {
                    lock.unlock();
                }
            }
        });

        b.start();
        a.start();
    }
}

参考文章

面试题:线程A打印1-10数字,打印到第5个数字时,通知线程B

结语

本人所有博客仅用于学习记录,不做任何商业用途,如涉及侵权,还请联系删除,感谢阅读,欢迎留言,一起进步~

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