有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC…

35 篇文章 0 订阅
12 篇文章 0 订阅

题目:有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC… 

方法一:使用lock和condition来实现a执行完通知b执行,b执行完通知c执行,c执行完通知a执行的顺序,使用Executors的fixedthreadpool,将三个线程放到线程池里面,使用线程池控制程序的结束,调用shutdown()方法。

package com.ljf.thread.demo.lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Resources {
    public static String threadName="A";//默认值为A;
    public static  Lock lock=new ReentrantLock();
    public static  Condition conA=lock.newCondition();
    public static  Condition conB=lock.newCondition();
    public static  Condition conC=lock.newCondition();

}

package com.ljf.thread.demo.lock;

public class ThreadA implements Runnable{

    public void run() {
     for(int k=0;k<10;k++){
         Resources.lock.lock();
         try {
             while(!Resources.threadName.equals("A")){
                 try {
                     Resources.conA.await();
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
             //打印信息
             System.out.println(String.format("这是第%d遍执行",k+1));
             System.out.println("A");
             //唤醒b
             Resources.threadName="B";
             Resources.conB.signal();
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             Resources.lock.unlock();
         }

     }
    }
}

package com.ljf.thread.demo.lock;

public class ThreadB implements Runnable {
    public void run() {
        for(int k=0;k<10;k++){
            Resources.lock.lock();
            try {
                while(!Resources.threadName.equals("B")){
                    try {
                        Resources.conB.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //打印信息
                System.out.println(String.format("这是第%d遍执行",k+1));
                System.out.println("B");
                //唤醒b
                Resources.threadName="C";
                Resources.conC.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                Resources.lock.unlock();
            }

        }
    }
}

package com.ljf.thread.demo.lock;

public class ThreadC implements  Runnable{
    public void run() {
        for(int k=0;k<10;k++){
            Resources.lock.lock();
            try {
                while(!Resources.threadName.equals("C")){
                    try {
                        Resources.conC.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //打印信息
                System.out.println(String.format("这是第%d遍执行",k+1));
                System.out.println("C");
                //唤醒b
                Resources.threadName="A";
                Resources.conA.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                Resources.lock.unlock();
            }

        }

    }
}
package com.ljf.thread.demo.lock;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class TestABC {
    public static void main(String args[]){
        ExecutorService es= Executors.newFixedThreadPool(3);
        es.execute(new ThreadA());
        es.execute(new ThreadB());
        es.execute(new ThreadC());
        es.shutdown();

    }
}

结果:

这是第1遍执行
A
这是第1遍执行
B
这是第1遍执行
C
这是第2遍执行
A
这是第2遍执行
B
这是第2遍执行
C
这是第3遍执行
A
这是第3遍执行
B
这是第3遍执行
C
这是第4遍执行
A
这是第4遍执行
B
这是第4遍执行
C
这是第5遍执行
A
这是第5遍执行
B
这是第5遍执行
C
这是第6遍执行
A
这是第6遍执行
B
这是第6遍执行
C
这是第7遍执行
A
这是第7遍执行
B
这是第7遍执行
C
这是第8遍执行
A
这是第8遍执行
B
这是第8遍执行
C
这是第9遍执行
A
这是第9遍执行
B
这是第9遍执行
C
这是第10遍执行
A
这是第10遍执行
B
这是第10遍执行
C

Process finished with exit code 0

https://mouselearnjava.iteye.com/blog/1949228

方法二:使用lock,通过公共统计次数来做判断实现顺序打印的,一个线程释放锁之后,自己和其他线程同时还会去抢夺公共锁,拿到锁且while里面的判读条件满足之后,才能打印。

package com.ljf.interview.thread;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;

public class Resource {
    public static int count=10;
    public static int cnt=0;
    public static   ReentrantLock locks=new ReentrantLock();
}

package com.ljf.interview.thread;

public class PrintA implements  Runnable{



    @Override
    public void run() {

      for(int k=0;k<10;){
          try {
              Resource.locks.lock();
              System.out.println("aaaa");
              while (Resource.cnt % 3 == 0) {//多线程并发,不能用if,必须用循环测试等待条件,避免虚假唤醒
                  System.out.print("A");
                  Resource.cnt++;
                  k++;
              }
          } finally {
              Resource.locks.unlock();// lock()和unlock()操作结合try/catch使用
          }

      }
    }
}
package com.ljf.interview.thread;

public class PrintB implements Runnable {
    @Override
    public void run() {

        for (int k = 0; k < 10; ) {
            try {
                Resource.locks.lock();
                System.out.println("bbbb");
                while (Resource.cnt % 3 == 1) {//多线程并发,不能用if,必须用循环测试等待条件,避免虚假唤醒
                    System.out.print("B");
                    Resource.cnt++;
                    k++;
                }
            } finally {
                Resource.locks.unlock();// lock()和unlock()操作结合try/catch使用
            }
        }
    }
}
package com.ljf.interview.thread;

import java.util.concurrent.locks.ReadWriteLock;

public class PrintC implements Runnable{
    @Override
    public void run() {

        for(int k=0;k<10;){
            try {
                Resource.locks.lock();
                System.out.println("ccc");
                while (Resource.cnt % 3 == 2) {//多线程并发,不能用if,必须用循环测试等待条件,避免虚假唤醒
                    System.out.print("C");
                    Resource.cnt++;
                    k++;
                }
            } finally {
                Resource.locks.unlock();// lock()和unlock()操作结合try/catch使用
            }
        }
    }
}
package com.ljf.interview.thread;

public class PrintTask   {
   public static void main(String args[]){
      new Thread(new PrintA(),"1").start();

      new Thread(new PrintC(),"3").start();
      new Thread(new PrintB(),"2").start();
   }
}

结果:

ABCABCABCABCABCABCABCABCABCABC

都看到这里了,就顺手点击左上角的【关注】按钮,点击右上角的小手,给个评论,关注一下,再走呗!☺

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值