两个线程1-100轮流打印

298 阅读1分钟

两个线程1-100轮流打印

第一种方法: synchronized关键字

static int num=0;
  public static void main(String[] args) {
    Object o = new Object(); //要锁住的资源类
    Runnable runnable =
        new Runnable() {
          @Override
          public void run() {
            while (num < 100) {
                synchronized (o) {
                o.notify();
                num++;
                System.out.println(Thread.currentThread().getName() + ":" + num);
                try {
                //避免b线程最后不能被唤醒一直等待导致线程不结束
                  if(num<100){
                    o.wait();
                  }else {
                    o.notify();
                  }
                } catch (Exception e) {
                  e.printStackTrace();
                }
              }
            }
            System.out.println(Thread.currentThread().getName()+"结束");
          }
        };

    new Thread(runnable,"a").start();
    new Thread(runnable,"b").start();
  }

第二种方法: ReentrantLock 的 Condition

public class ShareCahe {
    private  int num = 0;
    private static boolean flag = true;
    private static Lock lock = new ReentrantLock();
    private static Condition condition1 = lock.newCondition();
    private static Condition condition2 = lock.newCondition();

  public  int getNum() {
    return num;
  }

  public void condition1AddOne(){
      lock.lock();
      try{
        while(!flag){
          condition1.await();
        }
        if(num<100){
          num++;
          System.out.println(Thread.currentThread().getName()+":"+num);
        }
        flag = false;
        condition2.signal();
      } catch (InterruptedException e) {
        e.printStackTrace();
      } finally{
        lock.unlock();
      }
    }

    public void condition2AddOne(){
      lock.lock();
      try{
        while(flag){
          condition2.await();
        }
        if(num<100){
          num++;
          System.out.println(Thread.currentThread().getName()+":"+num);
        }
        flag=true;
        condition1.signal();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }finally{
        lock.unlock();
      }
    }
    
  public static void main(String[] args) throws InterruptedException {
      ShareCahe shareCahe = new ShareCahe();
      new Thread(()->{
        while(shareCahe.getNum()<100){
          shareCahe.condition1AddOne();
        }

      },"a").start();

    new Thread(
            () -> {
              while (shareCahe.getNum()<100) {
                shareCahe.condition2AddOne();
              }
            },
            "b")
        .start();
    Thread.sleep(200);
    System.out.println("====="+shareCahe.getNum());
  }
}

利用condition的话是可以完成多个线程轮流打印的,不只是两个线程,这里的思想就在于,我利用了一个flag 来表示标志位,当flag为true时,线程a开始执行执行完后把flag置为false,否则调用await(),让出锁资源,并让自己处于等待状态。b线程也是同理,只是b线程是flag为false才执行,通过两个线程的自己等待,对方唤醒来达到相互执行的效果