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下来,看到每个线程的状态,比如阻塞等。这是一个很好的方法。

posted on 2017-12-08 23:50  luckygxf  阅读(294)  评论(0编辑  收藏  举报

导航