三个线程循环输出字符

见到一个面试题,三个线程循环输出字符,自己实现一下。

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Chenfei
 */
public class Test {
    public static void main(String[] args) {
        Flag flag = new Test().new Flag();
        new Thread(new Test().new Print(new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'}, flag, 1)).start();
        new Thread(new Test().new Print(new char[]{'1', '2', '3', '4', '5', '6', '7', '8'}, flag, 2)).start();
        new Thread(new Test().new Print(new char[]{'!', '@', '#', '$', '%', '^', '&', '*'}, flag, 3)).start();
    }

    class Print implements Runnable {
        char[] strs = null;
        Integer idx = null;
        Flag flag = null;

        public Print(char[] strs, Flag flag, Integer idx) {
            this.strs = strs;
            this.flag = flag;
            this.idx = idx;
        }

        @Override
        public void run() {
            int i = 0;
            while (true) {
                synchronized (flag) {
                    // 判断是哪一个线程获取到锁,若非符合规则的线程获取到锁,则等待
                    if (flag.getI() % 3 != idx.intValue() % 3) {
                        try {
                            flag.wait();
                            // 被唤醒后的线程必须重新进入循环,判断是否符合重入规则
                            continue;
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    int m = i % strs.length;
                    System.out.printf("%s\t%s\t%s:%c\n", flag.getI(), flag.getI() % 3, idx.intValue(), strs[m]);
                    i++;
                    // 输出字符后标志位 +1
                    flag.atomic();
                    // 唤醒所有线程,让他们重新竞争锁
                    flag.notifyAll();
                    // 打印出前5个字母后退出循环
                    if (i == 5) {
                        return;
                    }
                }

            }
        }
    }

    /**
     * 锁对象,用来作为
     */
    class Flag {
        AtomicInteger i = new AtomicInteger(1);

        public int getI() {
            return i.intValue();
        }

        public void atomic() {
            i.incrementAndGet();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值