Java 7 Synchronized 方法似乎允许多线程访问

标签 java multithreading synchronized

我在 Java 7 应用程序上实现 Synchronized 接口(interface)时遇到问题。我认为问题可能在于我正在使用同步方法中写入的静态最终数组实例化多个对象。似乎线程没有确认监视器?我什至可以做我想做的事,还是我需要某种具有数组和 writeIndex 增量器的缓冲区对象? (如果有帮助,代码在 https://github.com/dschaper/CS112_Dan_Schaper/tree/master/Week14/Labs,这不是家庭作业,这只是一个不评分的实验。)

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 java.util.concurrent.ThreadPoolExecutor@544ec1[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 java.util.concurrent.ThreadPoolExecutor@544ec1[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 java.util.concurrent.ThreadPoolExecutor@544ec1[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: java.util.concurrent.ThreadPoolExecutor@544ec1[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

最佳答案

SD1、SD2 和 SD3 是不同对象,即它们不共享同一个监视器。每个对象都有自己的监视器。如果您想在所有实例之间共享监视器,您可以使用 synchronized(SingleDice.class) {...}。

关于Java 7 Synchronized 方法似乎允许多线程访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20253257/

相关文章:

java - 安卓安装异常 : EOF Google MapsView "Hello Maps"

java - Google App Engine Java 是否支持 Eclipse 中的热部署?

java - 没有打印语句,循环看不到其他线程更改的值

c++ - 如何在pthread线程中创建memcpy?

java - 使用 Spring 和 Hibernate 在 Multi-Tenancy 环境中访问数据的策略

Java:线程间共享和调用变量

java - 并发HashMap线程安全和happens-before关系

java - JAXB 编码一个具有 java.lang.Object 字段的对象

java - 多个ClassLoader如何从不同位置加载同名资源?

java - 如何在不关闭服务器套接字的情况下在客户端获得确认?