经典面试题:俩线程交替打印数字字母 例如:1A2B3C4D
骚操作:利用阻塞队列实现

        ArrayBlockingQueue queue1 = new ArrayBlockingQueue(1);
        //有界队列里面只有一个
        ArrayBlockingQueue queue2 = new ArrayBlockingQueue(1);

        char[] a = {'1', '2', '3'};
        char[] b = {'a', 'b', 'c'};

        new Thread(() -> {
            for (char c : a) {
                try {
                    //如果容器为空  put 会等待
                    queue1.put(c);
                    System.out.println(queue2.take());
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }, "t1").start();

        new Thread(() -> {
            for (char f : b) {
                try {
                //take 容器为空 也等待 
                    System.out.println(queue1.take());
                    //指定q2 put
                    queue2.put(f);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }, "t2").start();
// 每次队列只有1个 t1线程打印t2 t2打印t1
//输出 就是 1A2B3C

2.利用 synchronized同步锁 wait() notify(notifyAll)


    /** 定义对象锁 */
    final Object obj = new Object();

    char[] charsA = new char[] {'A', 'B', 'C', 'D'};
    char[] charsB = new char[] {'1', '2', '3', '4'};

    /** 线程 1 */
    new Thread(
            () -> {
              /** 对象锁 */
              synchronized (obj) {
                for (char c : charsB) {
                  System.out.println(c);
                  try {
                    /** 叫醒 */
                    obj.notify();
                    /** 等待 让出锁 */
                    obj.wait();
                  } catch (InterruptedException e) {
                    e.printStackTrace();
                  }
                }
                // 让线程终止
                obj.notify();
              }
            },
            "t1")
        .start();

    new Thread(
            () -> {
              synchronized (obj) {
                for (char b : charsA) {
                  System.out.println(b);
                  try {
                    obj.notify();
                    obj.wait();
                  } catch (InterruptedException e) {
                    e.printStackTrace();
                  }
                }
                obj.notify();
              }
            },
            "t2")
        .start();
  }

-----------------------------------------------------------

        char[] a = {'1', '2', '3', '4', '5'};
        char[] b = {'A', 'B', 'C', 'D', 'E'};

        //打印 1A2B。。。
        //wait notify()
        final Object lock = new Object();

        new Thread(() -> {
            synchronized (lock) {
                for (char zimu : b) {
                    //wait
                    try {
                        lock.wait();
                        System.out.println(zimu);
                        lock.notify();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "t1").start();

        new Thread(() -> {
            synchronized (lock) {
                for (char zimu : a) {
                    System.out.println(zimu);
                    //
                    lock.notify();

                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }


            }
        }, "t1").start();


    }

3.自旋锁 + volatile 实现

 enum flag {T1,T2};

   //线程可见性
    private static volatile flag r=flag.T1;


    public static void main(String[] args) {


        char[] charsA=new char[]{'A','B','C','D'};
        char[] charsB=new char[]{'1','2','3','4'};

        new Thread(()->{
             for (char a:charsB){
                 //无锁 自旋 首先 打印数字 
                 // 只能使用while 不能使用if
                 while (r!=flag.T1){}
                 System.out.println(a);
                 r=flag.T2;

             }
        },"t1").start();

        new Thread(()->{
            for (char a:charsA){
                while (r!=flag.T2){}
                System.out.println(a);
                r=flag.T1;

            }
        },"t2").start();
    }

  1. lock 锁实现

     ReentrantLock lock=new ReentrantLock();
    
         char[] a="123456".toCharArray();
         char[] b="ABCEFG".toCharArray();
         //条件判断 可以精确指定 那个线程先执行
         Condition t1= lock.newCondition();
         Condition t2= lock.newCondition();
    
         new Thread(()->{
             lock.lock();
             try {
                 for (char v:a){
                     System.out.println(v);
                     t2.signal();
                     t1.await();
                 }
                 t2.signal();
             }catch (Exception ex){
                 ex.printStackTrace();
    
             }finally {
                 lock.unlock();
             }
         },"t1").start();
    
    
         new Thread(()->{
             lock.lock();
             try {
                 for (char v:b){
                     System.out.println(v);
                     t1.signal();
                     t2.await();
                 }
                 t1.signal();
             }catch (Exception ex){
                 ex.printStackTrace();
    
             }finally {
                 lock.unlock();
             }
    
         },"t1").start();
    
     }
    
  2. SynchronousQueue 必须消费 容量为0

    
         //同步队列 容量为0 必须消费
         SynchronousQueue<Object> queue1 = new SynchronousQueue<>();
         SynchronousQueue<Object> queue2 = new SynchronousQueue<>();
    
         char[] chars = {'1', '2', '3', '4', '5'};
         char[] zim = {'A', 'B', 'C', 'D', 'F'};
    
         new Thread(() -> {
             for (char c : zim) {
                 try {
                   System.out.println(queue2.take());
                   queue1.put(c);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
         }, "t1").start();
    
         new Thread(() -> {
    
             for (char c : chars) {
                 try {
                     queue2.put(c);
                     System.out.println(queue1.take());
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
    
    
             }
    
         }, "t2").start();
    
    
     }

方法还是很多的..


Redorblack
39 声望0 粉丝

后端菜鸟记录美好生活