java实现多线程打印ABCD

题目描述:
  • 问题描述:有4个线程和1个公共的字符数组。
  • 线程1的功能就是向数组输出A,线程2的功能就是向字符输出B,线程3的功能就是向数组输出C,
  • 线程4的功能就是向数组输出D。要求按顺序向数组赋值ABCDABCDABCD,ABCD的个数由线程函数1的参数指定
示例1
  • 输入
    10
  • 输出
    ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD
实现思路:
  • 让A线程分配对象锁a,b。
  • 让B线程分配对象锁b,c。
  • 让C线程分配对象锁c,d。
  • 让D线程分配对象锁d,a。
  • 接下就是重点,我们会用Objcet类中的wait()方法和notify()方法。
  • wait():等待,如果线程执行了wait方法,那么该线程会进入等待的状态,等待状态下的线程必须要被其他线程调用notify()方法才能唤醒。wait()方法执行后,当前线程释放锁,其他线程可以竞争该锁。
  • notify()方法执行后,唤醒线程不会立刻释放锁,要等唤醒线程全部执行完毕后才释放对象锁。
  • 我们要做的就是在A线程在执行打印“A”后,就唤醒B线程,然后让A线程进入等待。以此类推,B线程在执行打印“B”后,就唤醒C线程,然后让B线程进入等待。C线程在执行打印“C”后,就唤醒D线程,然后让C线程进入等待。D线程在执行打印“D”后,就唤醒A线程,然后让D线程进入等待。
  • 这里有个问题我们在启动线程的时候为了确保A线程先打印,我们在初始化线程的时候在线程中增加了两个静态变量newIndex,runIndex。(静态变量的值是所有线程共享的)给线程分别制定相对应的id。id = newIndex++线程执行之后runIndex++。初始化A线程id为0,runIndex为0,B线程为1,runIndex为1,C线程为2,runIndex为2,D线程为3,runIndex为3,当id > runIndex 时说明这个线程是首次执行且还不应该到它执行打印,所以把它在外层synchronized的对象上休眠等待它上一个线程执行答应后唤醒它。
  • 在判断此次打印不是最后一次后则让该线程进入等待。
package huaweijishi;

import java.util.Scanner;

/**
 * 题目描述
 * 问题描述:有4个线程和1个公共的字符数组。
 * 线程1的功能就是向数组输出A,线程2的功能就是向字符输出B,线程3的功能就是向数组输出C,
 * 线程4的功能就是向数组输出D。要求按顺序向数组赋值ABCDABCDABCD,ABCD的个数由线程函数1的参数指定
 */
public class test19 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            int num = scanner.nextInt();
            Object a = new Object();
            Object b = new Object();
            Object c = new Object();
            Object d = new Object();
            Thread thread1 = new Thread(new ThreadPrintAbcd("A",a,b,num));
            Thread thread2 = new Thread(new ThreadPrintAbcd("B",b,c,num));
            Thread thread3 = new Thread(new ThreadPrintAbcd("C",c,d,num));
            Thread thread4 = new Thread(new ThreadPrintAbcd("D",d,a,num));

            thread1.start();
            thread2.start();
            thread3.start();
            thread4.start();

        }
    }
}
class ThreadPrintAbcd implements Runnable{
    private static int newIndex=0;
    private static int runIndex=0;
    private boolean isFirstRun=true;
    private Object self;
    private Object next;
    private String name;
    private int id;
    private int num;

    public ThreadPrintAbcd(String name,Object self,Object next,int num){
        id = newIndex++;
        this.name = name;
        this.self = self;
        this.next = next;
        this.num = num;
    }
    @Override
    public void run() {
        while (num > 0){
        synchronized(self){
                if(id > runIndex){
                    try {
                        self.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.print(name);
                if(isFirstRun){
                    runIndex ++;
                    isFirstRun=false;
                }
            synchronized (next) {
                next.notify();
            }
                num--;
                if(num >0){
                    try {
                        self.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

运行结果

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

java小黑仔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值