关于java:经典问题-俩线程交替打印数字字母

5次阅读

共计 2683 个字符,预计需要花费 7 分钟才能阅读完成。

经典面试题:俩线程交替打印数字字母 例如: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();}
    

    办法还是很多的..

正文完
 0