使用令牌和字符打印的Java线程同步
好的,我最近一直在尝试理解线程和线程同步。我已经写了一个程序,应该输出abc,按照这个顺序,一次又一次地将每个字符映射到一个线程。问题是,它不起作用,我不知道为什么。这是我的密码:使用令牌和字符打印的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
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链接的问题所示,您还在等待操作中解锁。您在等待循环外等待。这与并发线程的概念相反,即它们异步工作。这很难,因为你想用螺丝刀把钉子钉进去。