countdownlatch

it2023-06-20  68

 一道面试题:实现一个容器,提供两个方法,add,size,写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束线程2

第一种,使用wait()和notify()来实现

public class test {     volatile List lists = new ArrayList();

    public void add(Object o){         lists.add(o);     }

    public int size(){         return lists.size();     }

    public static void main(String[] args) {         test c = new test();         Object lock = new Object();         new Thread(()->{             synchronized (lock) {                 System.out.println("t2启动");                 if (c.size() != 5) {                     try {                     lock.wait();//释放锁                     } catch (Exception e) {                         e.printStackTrace();                     }                 }                 System.out.println("t2结束");                 lock.notify();             }         }," t2").start();         new Thread(()->{             System.out.println("t1启动");             synchronized (lock) {                 for (int i = 0; i < 10; i++) {                     c.add(new Object());                     System.out.println("add " + i);                     if (c.size() == 5) {                         lock.notify();//唤醒当前等待线程,但是不会释放当前线程持有的锁,所以T2线程无法获得锁,依然无法执行                         try {                             lock.wait();//释放锁,T2才能得到锁得以执行                         } catch (Exception e) {                             e.printStackTrace();                         }                     }                     try {                         TimeUnit.SECONDS.sleep(1);                     } catch (Exception e) {                         e.printStackTrace();                     }                 }             }         }, "t1").start();

    }

}

第二种方法,可以使用CountDownLatch来进行控制

public class test {

    volatile List lists = new ArrayList();

    public void add(Object o){         lists.add(o);     }

    public int size(){         return lists.size();     }

    public static void main(String[] args) {         test c = new test();

        CountDownLatch latch = new CountDownLatch(5);

        new Thread(()->{             System.out.println("t2启动");             if (c.size() != 5) {                 try {                     latch.await();//准备                 } catch (Exception e) {                     e.printStackTrace();                 }                 System.out.println("t2结束");             }         }," t2").start();

        new Thread(()->{             System.out.println("t1启动");             for (int i = 0; i < 10; i++) {                 c.add(new Object());                 System.out.println("add " + i);                 if (c.size() == 5) {                     latch.countDown();//减一操作                 }                 try {                     TimeUnit.SECONDS.sleep(1);                 } catch (Exception e) {                     e.printStackTrace();                 }             }         }, "t1").start();     }

}

CountDownLatch 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了

最新回复(0)