zoukankan      html  css  js  c++  java
  • Java线程同步打印ABC

    需求:

    三个线程,依次打印ABCABCABC....

    方案一:

    使用阻塞队列,线程1从队列1获取内容打印,线程2从队列2获取内容打印,线程3从队列3中获取内容打印。线程1把B放到队列3中,线程2把C放到队列3中,线程3把A放到队列1中。

    demo:

    demo里面防止打印太快,使用了Thread.sleep(1000),以及原子变量,记录打印次数。

    PrintTask.java
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     * Created by GuanXF on 2017/12/8.
     */
    public class PrintTask {
        private static BlockingQueue<Character>[] blockingQueues = new BlockingQueue[]{new LinkedBlockingQueue(),new LinkedBlockingQueue(), new LinkedBlockingQueue()};
        private static AtomicInteger printCount = new AtomicInteger(0);
    
        public static void main(String[] args) {
            Thread t1 = new Thread(new PrintA());
            Thread t2 = new Thread(new PrintB());
            Thread t3 = new Thread(new PrintC());
            t1.start();
            t2.start();
            t3.start();
        }
    
        static class PrintA implements Runnable{
    
            public void run() {
                while(true){
                    try {
                        System.out.println(blockingQueues[0].take());
                        blockingQueues[1].put('B');
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                }
            }
        }
    
        static class PrintB implements Runnable{
    
            public void run() {
                while(true){
                    try {
                        System.out.println(blockingQueues[1].take());
                        blockingQueues[2].put('C');
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                }
            }
        }
    
        static class PrintC implements Runnable{
    
            public void run() {
                while(true){
                    try {
                        blockingQueues[0].put('A');
                        System.out.println(blockingQueues[2].take());
                        System.out.println("----------------" + printCount.incrementAndGet() +  "------------------");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                }
            }
        }
    }

    方案二:

    使用整型变量记录那个值该哪个线程打印,比如 state % 3 == 0线程1打印A,state % 3 == 0线程2打印B,state % 3 == 0线程3打印C

     demo

    PrintTaskUseState.java
    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     * Created by GuanXF on 2017/12/8.
     */
    public class PrintTaskUseState {
        private static AtomicInteger state = new AtomicInteger(0);
        private static AtomicInteger printCount = new AtomicInteger(0);
    
    
        public static void main(String[] args) {
            Thread t1 = new Thread(new PrintA(), "---PrintA----");
            Thread t2 = new Thread(new PrintB(), "---PrintB----");
            Thread t3 = new Thread(new PrintC(), "---PrintC----");
            t1.start();
            t2.start();
            t3.start();
        }
    
        static class PrintA implements Runnable{
    
            public void run() {
                while(true){
                    if(state.get() % 3 == 0){
                        System.out.println('A');
                        state.getAndIncrement();
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    
        static class PrintB implements Runnable{
    
            public void run() {
                while(true){
                    if(state.get() % 3 == 1){
                        System.out.println('B');
                        state.getAndIncrement();
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    
        static class PrintC implements Runnable{
    
            public void run() {
                while(true){
                    if(state.get() % 3 == 2){
                        System.out.println('C');
                        state.set(0);
                        System.out.println("----------------" + printCount.incrementAndGet() +  "------------------");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

     备注,在第二个demo使用了命名线程,可以使用jstack -l pid把进程dump下来,看到每个线程的状态,比如阻塞等。这是一个很好的方法。

  • 相关阅读:
    SQL事务
    C# 怎样读写EXCEL文件
    如何#读写EXCEL 文件 (http://space.cnblogs.com/question/7131/)
    C# 怎样读写EXCEL文件 (http://space.cnblogs.com/question/7131/)
    控制DataGirdView中單元格
    C#中ToString格式大全
    转贴:用SqlCommandBuilder 实现批量更新
    错题记录1
    Java—关于String的分析
    Java模拟双色球彩票
  • 原文地址:https://www.cnblogs.com/luckygxf/p/8007553.html
Copyright © 2011-2022 走看看