Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用令牌和字符打印的Java线程同步_Java_Multithreading_Synchronization_Synchronized - Fatal编程技术网

使用令牌和字符打印的Java线程同步

使用令牌和字符打印的Java线程同步,java,multithreading,synchronization,synchronized,Java,Multithreading,Synchronization,Synchronized,好的,我最近一直在尝试理解线程和线程同步。我已经写了一个程序,应该输出abc,按照这个顺序,一次又一次地将每个字符映射到一个线程。问题是,它不起作用,我不知道为什么。这是我的密码: package application2; public class Application2 { private static int turn = 0; private static String[] names = new String[3]; private static class syncThrea

好的,我最近一直在尝试理解线程和线程同步。我已经写了一个程序,应该输出abc,按照这个顺序,一次又一次地将每个字符映射到一个线程。问题是,它不起作用,我不知道为什么。这是我的密码:

package application2;

public class Application2 {

private static int turn = 0;
private static String[] names = new String[3];

private static class syncThreads extends Thread {

    private final char charToPrint;
    //private final int times;

    public syncThreads(char charToPrint) {
        this.charToPrint = charToPrint;
        //this.times = times;
    }

    @Override
    public synchronized void run() {
        String myName = Thread.currentThread().getName();
        for (int i = 0; i < 20; i++) {
            if (myName.equals(names[turn])) {
                System.out.print(charToPrint);
            }
            turn++;
            if (turn == 3) {
                turn = 0;
            }
        }

        notifyAll();
        try {
            Thread.currentThread().wait(200);
        } catch (InterruptedException e) {

        }
    }

}

public static void main(String args[]) {

    syncThreads t1 = new syncThreads('a');
    names[0] = t1.getName();
    syncThreads t2 = new syncThreads('b');
    names[1] = t2.getName();
    syncThreads t3 = new syncThreads('c');
    names[2] = t3.getName();

    t1.start();
    t2.start();
    t3.start();

    //Join method ensures proper synchronization
    try {
        t1.join();
        t2.join();
        t3.join();
    } catch (Exception e) {
        System.out.println("Interrupt Exception.");
    }

}
}
如您所见,我尝试使用一个同步运行函数,该函数使用一个令牌值来告诉要打印的线程。当我运行这个程序时,我得到了非常奇怪的结果,比如aaaaaa bbbbccc和abbabaaaccbbccc,等等。你知道为什么这些线程没有被同步吗?我错过了什么


谢谢你的帮助

如前所述,试图让各个线程按顺序运行会破坏整个并发点。如果你想要的话,就把它们放在一根线里。另一方面,如果您想确保所有三个线程都已运行,然后再让它们重新启动,那么这相当容易:

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Sync {
    private static final CyclicBarrier barrier = new CyclicBarrier(3);

    public static void main(String[] args) {
        new Thread(new CharPrinter('a')).start();
        new Thread(new CharPrinter('b')).start();
        new Thread(new CharPrinter('c')).start();
    }

    public static class CharPrinter implements Runnable {
        private char c;
        private int times = 10;

        public CharPrinter(char c) {
            this.c = c;
        }

        @Override
        public void run() {
            while(times-- > 0) {
                System.out.print(c);
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                } catch (BrokenBarrierException e) {  }
            }
        }
    }
}

为了清晰起见,这将添加bac/cba/acb/bca/abc/cab/bca/abc/cab/bca斜线之类的输出。请注意,您总是在每组三个字符中获得a、b和c输出,但顺序是不确定的-这对于并发线程来说应该是这样。

您不仅在错误的事情上同步了这一点,而且在共享对象上同步了,如Chris链接的问题所示,您还在等待操作中解锁。您在等待循环外等待。这与并发线程的概念相反,即它们异步工作。这很难,因为你想用螺丝刀把钉子钉进去。