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

标签 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 并发高级对象之一
  • 不应使用隐式锁定同步 等待 通知
  • 必须使用 System.out.print() 打印单个字符
  • 使用 3 个线程,每个线程必须打印其名称(颜色)
  • 应按 RED BLUE GREEN 的顺序打印

最佳答案

    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,并使用它来定义允许锁定和解锁线程的新策略。

关于java - 使用 System.out.print 按顺序打印 RED BLUE GREEN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18591463/

相关文章:

java - 用于与 Web 服务同步的 Android 后台作业

java - 在 Mockito 中 stub 方法时,我应该使用原始实例还是 stub 实例进行测试?

java - 在MongoDB中,Java驱动程序如何将 "explain"与聚合一起使用?

c++ - 如何使用多线程处理缓存数据结构(例如 openmp)

for 循环中的 C++ 11 线程类成员函数给出段错误

java - 更新 JFrame 中的 JPanel

Java 词搜索求解器设计方法

java - JMH 中 hs_gc 分析器计数器的含义

python - 一起使用模拟 (MyHDL) 和 wxPython

Node.js Cluster + Express 始终调用同一个工作线程