我在Java 7应用程序上实现Synchronized接口时遇到问题。我认为这个问题可能在于,我正在使用在synchronized方法中写入的静态最终数组实例化多个对象。看起来线程没有确认显示器?我甚至可以做我想做的事情,还是我需要某种具有数组和writeIndex增量器的缓冲区对象? (如果有帮助,代码为https://github.com/dschaper/CS112_Dan_Schaper/tree/master/Week14/Labs这不是功课,这仅仅是一个非分级实验室。)Java 7同步方法似乎允许多线程访问
public class SingleDice extends Dice implements Runnable {
String threadName;
private static final int[] valuesArray = new int[9];
private static int writeIndex = 0;
public SingleDice(String tName) {
super(1);
threadName = tName;
}
public synchronized void add(int value) {
int pos = writeIndex;
System.out.printf("%s starting sync add(%d), writeIndex = %d\n",
Thread.currentThread().getName(), value,
writeIndex);
valuesArray[pos] = value;
System.out.printf("%s wrote %d to index %d\n",
Thread.currentThread().getName(), value, writeIndex);
++writeIndex;
System.out.printf("Next writeIndex %d\n", writeIndex);
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
add(super.Throw());
}
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SyncDiceExecutor {
public static void main(String[] args) {
System.out.println("Creating newCachedThreadPool");
SingleDice SD1 = new SingleDice("SD1");
SingleDice SD2 = new SingleDice("SD2");
SingleDice SD3 = new SingleDice("SD3");
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(SD1);
System.out.printf("Starting Thread SD1 %s\n", executor.toString());
executor.execute(SD2);
System.out.printf("Starting Thread SD2 %s\n", executor.toString());
executor.execute(SD3);
System.out.printf("Starting Thread SD3 %s\n", executor.toString());
executor.shutdown();
System.out.printf("Execeutor shutdown called: %s\n", executor.toString());
}
}
输出
Creating newCachedThreadPool
Starting Thread SD1 [email protected][Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
pool-1-thread-1 starting sync add(4), writeIndex = 0
pool-1-thread-2 starting sync add(4), writeIndex = 0
Starting Thread SD2 [email protected][Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0]
pool-1-thread-2 wrote 4 to index 0
pool-1-thread-1 wrote 4 to index 0
pool-1-thread-3 starting sync add(4), writeIndex = 1
Next writeIndex 1
pool-1-thread-2 starting sync add(6), writeIndex = 2
Starting Thread SD3 [email protected][Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
pool-1-thread-2 wrote 6 to index 2
Next writeIndex 3
pool-1-thread-3 wrote 4 to index 2
Next writeIndex 4
Next writeIndex 2
pool-1-thread-3 starting sync add(1), writeIndex = 4
pool-1-thread-2 starting sync add(6), writeIndex = 3
Execeutor shutdown called: [email protected][Shutting down, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
pool-1-thread-2 wrote 6 to index 4
Next writeIndex 5
pool-1-thread-3 wrote 1 to index 4
Next writeIndex 6
pool-1-thread-1 starting sync add(3), writeIndex = 4
pool-1-thread-3 starting sync add(1), writeIndex = 6
pool-1-thread-1 wrote 3 to index 6
pool-1-thread-3 wrote 1 to index 6
Next writeIndex 8
Next writeIndex 7
pool-1-thread-1 starting sync add(1), writeIndex = 8
pool-1-thread-1 wrote 1 to index 8
Next writeIndex 9
Process finished with exit code 0
感谢您的帮助!所以这个方法显式地是'public synchronized void add(int value){synchronized(this)...}',就像我上面编码的那样? (正如@hyde指出的)我只需要明确地将(this)改为(SingleDice.class)。 – SonOfAMotherlessGoat
将方法签名中的'synchronized'与本方法中的'synchronized(this){method body}'做同样的处理。所以你可以从签名中除去'synchronized'并且在方法体上添加'synchronized(SingleDice.class){...}'。 – fpw
'public synchronized void add(int value){ synchronized(SingleDice.class){ int pos = writeIndex; valuesArray [pos] = value; System.out.printf(“%s写入%d到索引%d \ n”,(),value,writeIndex); ++ writeIndex; } }'抱歉,不知道如何在注释中做代码块 – SonOfAMotherlessGoat