使用System.out.print按顺序打印RED BLUE GREEN

时间:2013-09-03 11:43:33

标签: java multithreading concurrency synchronization java.util.concurrent

public class CyclicBar {
    private final static CyclicBarrier cb = new CyclicBarrier(3,
            new Runnable() {
                @Override
                public void run() {
                    System.out.println("\n-------------");
                }
            });

    public static void main(String[] args) {

        final class ColouredRunnable implements Runnable {
            private int i;

            public ColouredRunnable(int j) {
                this.i = j;
            }

            @Override
            public void run() {
                final String name = Thread.currentThread().getName();
                while (true) {
                    cyclicAwait();
                    for (int i = 0; i < name.length(); i++) {
                        sleep();
//                      System.out.print("" + name.charAt(i) + this.i + " ");
                        System.out.print("" + name.charAt(i) +  " ");
                    }
                }
            }
        }
        ;

        int i = 0;
        new Thread(new ColouredRunnable(i++), "RED").start();
        new Thread(new ColouredRunnable(i++), "BLUE").start();
        new Thread(new ColouredRunnable(i++), "GREEN").start();
    }

    private static int cyclicAwait() {
        try {
            return cb.await();
        } catch (InterruptedException | BrokenBarrierException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return -1;
    }

    private static void sleep() {
        try {
            Thread.sleep(ThreadLocalRandom.current().nextLong(200, 600));
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

以上代码目前正在打印

-------------
G R B R E L E E D U E N 
-------------
B R G E R L U E D E E N 
-------------
R G B E L R E U D E E N 
-------------
R G B E R L U E D E E N 
-------------
B R G E L D R U E E E N 
-------------

如何更改上述代码并在适当的位置添加适当的屏障以产生以下输出

-------------
R E D B L U E G R E E N 
-------------
R E D B L U E G R E E N 
-------------
R E D B L U E G R E E N 

约束

  • 必须使用现代java并发更高级别对象之一
  • 不应使用隐式锁定synchronised wait notify
  • 必须使用System.out.print()
  • 打印单个字符
  • 使用3个线程,每个线程必须打印其名称(颜色)
  • 应按RED BLUE GREEN
  • 的顺序打印

3 个答案:

答案 0 :(得分:1)

    public class TestSynMain {
    private final static AbstractQueuedSynchronizer cb = new TestSynchronizer(6);

    public static void main(String[] args) {

        final class ColouredRunnable implements Runnable {
            private String color;

            public ColouredRunnable(String color) {
                this.color = color;
            }

            @Override
            public void run() {
                while (true) {
                    try {
                        boolean result = false;
                        do{
                             result = cb.tryAcquireNanos(Integer.parseInt(Thread.currentThread().getName()), TimeUnit.MILLISECONDS.toNanos(1000));
                        }while(!result);

                        for (int i = 0; i < color.length(); i++) {
                            try {
                                Thread.sleep(300);
                            } catch (InterruptedException e) {
                                System.exit(-1);
                            }
                            System.out.print("" + color.charAt(i) +  " ");
                        }
                    } catch (NumberFormatException e1) {
                        e1.printStackTrace();
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }finally{
                        cb.release(Integer.parseInt(Thread.currentThread().getName()));
                    }
                }
            }
        }

        new Thread(new ColouredRunnable("RED"), "0").start();
        new Thread(new ColouredRunnable("BLUE"), "1").start();
        new Thread(new ColouredRunnable("GREEN"), "2").start();
        new Thread(new ColouredRunnable("BLACK"), "3").start();
        new Thread(new ColouredRunnable("MAGENTA"), "4").start();
        new Thread(new ColouredRunnable("WHITE"), "5").start();
    }
}

public class TestSynchronizer extends AbstractQueuedSynchronizer{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    int count;

    public TestSynchronizer(int count) {
        this.count = count;
        setState(0);
    }


    @Override
    protected boolean tryAcquire(int arg) {
        if(arg == getState()){
            System.out.println("Acquires" + Thread.currentThread().getName());
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }

    @Override
    protected boolean tryRelease(int arg) {
        int state = getState();
        setState(++state % count);
        setExclusiveOwnerThread(null);
        return true;
    }


}

如何使用它?

Synchronizer接受一个参数count,该参数最多可以同步多少个线程。

线程的名称必须是他们需要采取的订单。现在,您可以根据需要添加任意数量的线程。

我设计了一个自定义Synchronizer并用它来定义一个允许锁定和解锁线程的新策略。

答案 1 :(得分:1)

如果你想玩它们,Phasers也很酷。所有这一点要求你用你想要的任何单词填充words列表 - 它为每个单词创建一个主题并且它们都可以很好地运行。

public class PhaserTest
{
    private final Phaser phaser = new Phaser(1) {
        protected boolean onAdvance(int phase, int parties)
        {
            //Phaser version of your CyclicBarrier Runnable
            if(parties == 1)
                System.out.println("\n-------------");
            return false;
        }
    };

    public void runTest()
    {
        List<String> words = Arrays.asList("RED", "BLUE", "GREEN");

        for(int i = 0; i < words.size();i++)
            new Thread(new ColouredRunnable(words.get(i),i + 1)).start();

        while(phaser.arriveAndAwaitAdvance() != (words.size() + 1)){}
        System.out.println("Done.");
    }

    public class ColouredRunnable implements Runnable {
        private final int order;
        private final String color;

        public ColouredRunnable(String s, int order) {
            this.color = s;
            this.order = order;
            phaser.register();
        }

        @Override
        public void run() {
            while(phaser.arriveAndAwaitAdvance() != order){}

            for (int i = 0; i < color.length(); i++) {
                sleep();
                System.out.print("" + color.charAt(i) +  " ");
            }
            phaser.arriveAndDeregister();
        }

        private void sleep() {
            try {
                Thread.sleep(ThreadLocalRandom.current().nextLong(200, 600));
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

答案 2 :(得分:0)

此解决方案使用3个循环障碍。代码最初使用循环障碍在线程之间创建托管死锁。触发cb[cb.length-1].await();线程中的main

会破坏死锁
public static void main(String[] args) {
    String colors[] = { "RED", "BLUE", "GREEN" };
    final CyclicBarrier[] cb = createCB(colors);

    for (int i = 0; i < colors.length; i++) {
        final int j = i;

        new Thread(colors[i]) {
            public void run() {
                while (true) {
                    try {
                        cb[(j == 0 ? cb.length : j) - 1].await();// Wait for
                                                                    // previous
                                                                    // barrier
                        String name = getName();
                        for (int i = 0; i < name.length(); i++) {
                            CyclicBari.sleep();
                            System.out.print(" " + name.charAt(i) + " ");
                        }
                        cb[j].await();// Notify next
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            }

        }.start();
    }

    System.out.println("start");
    try {
        cb[cb.length-1].await();
    } catch (InterruptedException | BrokenBarrierException e) {
        e.printStackTrace();
    }

}

private static void sleep() {
    try {
        Thread.sleep(ThreadLocalRandom.current().nextLong(200, 600));
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

private static CyclicBarrier[] createCB(String[] colors) {
    final CyclicBarrier cb[] = new CyclicBarrier[colors.length];
    for (int i = 0; i < cb.length; i++) {
        final int j = i;
        cb[i] = new CyclicBarrier(2, new Runnable() {

            @Override
            public void run() {
                if (j == cb.length - 1) {
                    System.out.println("\n-------------");
                } else {
                    System.out.print(".");
                }
            }
        });

    }
    return cb;
}

输出

-------------
 R  E  D . B  L  U  E . G  R  E  E  N 
-------------
 R  E  D . B  L  U  E . G  R  E  E  N 
-------------
 R  E  D . B  L  U  E . G  R  E  E  N 
-------------