我刚刚开始玩多线程编程。我希望我的节目交替显示字符' - '和'+',但事实并非如此。我的任务是使用synchronized
关键字。到目前为止我已经:
class FunnyStringGenerator{
private char c;
public FunnyStringGenerator(){
c = '-';
}
public synchronized char next(){
if(c == '-'){
c = '+';
}
else{
c = '-';
}
return c;
}
}
class ThreadToGenerateStr implements Runnable{
FunnyStringGenerator gen;
public ThreadToGenerateStr(FunnyStringGenerator fsg){
gen = fsg;
}
@Override
public void run() {
for(int i = 0; i < 10; i++){
System.out.print(gen.next());
}
}
}
public class Main{
public static void main(String[] args) throws IOException {
FunnyStringGenerator FSG = new FunnyStringGenerator();
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 20; i++){
exec.execute(new ThreadToGenerateStr(FSG));
}
}
}
编辑:我还在运行方法中测试Thread.sleep
而不是for
循环。
答案 0 :(得分:5)
synchronized
中的FunnyStringGenerator.next()
阻止工作正常。它会交替返回'+'
和'-'
。
但是您在ThreadToGenerateStr.run()
中遇到了竞争条件:
System.out.print(gen.next());
这相当于:
char c = gen.next(); // Synchronized
System.out.print(c); // Not synchronized
问题发生在:
结果是'+'和' - '以相反的顺序写出。
有各种可能的解决方法,例如:
synchronized
块中调用gen.next()和System.out.print()(如dogbane的回答)答案 1 :(得分:3)
而不是同步方法,请执行以下操作:
synchronized (gen) {
System.out.print(gen.next());
}
您需要将整个print语句包装在synchronized块中,以便其他线程在打印之前无法更改c
的值。
将其视为两个陈述:
char n = gen.next();
System.out.print(n);
答案 2 :(得分:-1)
请使用两个线程打印每个字符,并使用等待和通知的概念。