1
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 的顺序打印
4

3 回答 3

1

如果你想和他们一起玩,移相器也很酷。所有这一切都需要你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();
            }
        }
    }
}
于 2013-09-20T01:23:46.447 回答
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并使用它来定义允许锁定和解锁线程的新策略。

于 2013-09-03T13:17:14.690 回答
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 
-------------
于 2013-09-26T23:05:11.353 回答