java八股文面试[多线程]——两个线程交替打印1-100之间的数字

一份代码,两个线程,使用synchronize实现:
  • 重写run()方法,将输出1到100之间整数的代码写到同步方法里。
  • 线程1进入到同步方法,输出一个整数后,阻塞并释放锁。
  • 线程2进入到同步方法,唤醒线程1,输出整数后,阻塞并释放锁。
  • 线程1和线程2重复第3步,直到输出所有的整数。
public class PrintNumThread extends Thread {
 
    static int num = 0;
    static Object object = new Object();
 
    @Override
    public void run() {
 
        while (true) {
 
            synchronized (object) {
                //唤醒等待的线程 必须在同步代码块中
                object.notify();
                if (num < 100) {
                    num++;
                    System.out.println(Thread.currentThread().getName()+":"+num);
                } else {
                    break;
                }
                try {
                    /*
                    wait()  必须在同步代码块中使用,
                            必须是使用同步锁调用wait()
                            wait()调用后,锁会释放
                            必须要通过其他线程来唤醒
                     */
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
 
    public static void main(String[] args) {
 
        PrintNumThread p1 = new PrintNumThread();
        PrintNumThread p2 = new PrintNumThread();
                       p1.start();
                       p2.start();
    }
}

两个不同的线程:

不使用锁,利用volatile实现

定义一个static的flag,交替修改0 1 ,

//两个线程,一个打印奇数,一个打印偶数
public class OneToHundred{
   static volatile int flag = 0;
   public static void main(String[] args){
      new Thread(new Task1(),"A").start();
      new Thread(new Task2(),"B").start();
   }
}

class Task1 implements Runnable{
   @Override
   public void run(){
     int i = -2;
     while(i<=99){
       if(OneToHundred.flag == 0){
          i+=2;
          System.out.println("a:" + i);
          OneToHundred.flag = 1;
       }
     }
   }
}

class Task2 implements Runnable{
   @Override
   public void run(){
     int i = -1;
     while(i<=98){
       if(OneToHundred.flag == 1){
          i+=2;
          System.out.println("b:" + i);
          OneToHundred.flag = 0;
       }
     }
   }
}
使用ReentranLock(固定一个打印奇数,一个打印偶数)
//三实现的方式,虽然也是一个打印奇数,一个打印偶数,但是A打印奇数还是偶数是随机的,即A打印奇数,则B打印偶
//如果A随机打印的是偶数,那么B打印奇数
//现在固定,A就是打印奇数,B就是打印偶数
public class OneToHundred {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread( new Task(1),"A");
        Thread t2 = new Thread( new Task(0),"B");
        t1.start();
        t2.start();
    }
}

class Task implements Runnable{
   private static int number = 0;
   private int flag = 0;
   private static ReentrantLock lock = new ReentrantLock();
   private static Condition condition = lock.newCondition();
   
   Task(int flag){
     this.flag = flag;
   }
   @Override
   public void run(){
     while(number < 100){
       lock.lock();
       if(number >=100) break;
       if(b % 2 == this.flag){
          flag++;
       }else{
          try{
            condition.await();
          }catch (InterruptedException e) {
            e.printStackTrace();
          } 
       }
       condition.signalAll();
       lock.unlock();
     }
   }
}

在Condition对象中,与wait() ,notify() ,notifyAll()方法分别对应的是await() , signal() ,signalAll()方法。Condition实例实质上被绑定到一个锁上要为特定Lock实例获得Condition实例,使用其newCondition()方法。
将第一个Number类改成以下代码,也可以实现一样的结果。
 

知识来源:

两个线程交替打印1-100之间的数字_线程交替打印1到100_叫我剑锋的博客-CSDN博客

两个线程交替打印1-100_两个线程交替打印1到100_一 路的博客-CSDN博客

两个线程交替打印1-100_两个线程交替打印1到100_一 路的博客-CSDN博客

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小田田_XOW

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值