簡體   English   中英

Java 7 Synchronized方法似乎允許多線程訪問

[英]Java 7 Synchronized method seems to allow multiple threads access

我在Java 7應用程序上實現Synchronized接口時遇到問題。 我認為問題可能在於我正在使用在synchronized方法中寫入的靜態最終數組來實例化多個對象。 似乎線程沒有確認監視器? 我是否可以做我正在嘗試做的事情,或者我是否需要某種具有數組和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){...}。

synchronized對非靜態方法同步this ,所以如果你有不同的對象,它們並不互相排斥。 如果您不能使用靜態方法(在類上進行同步),解決方案是添加靜態鎖定對象並對其進行同步以保護靜態數據。

static final Object valueArrayLock = new Object();

...

// inside a method
synchronized(valueArrayLock) {
    // operate on valueArray
}

注意,如果需要在靜態方法中鎖定它,請使用相同的靜態鎖定對象,而不是使靜態方法同步(或者查看有關使用類對象進行鎖定的其他答案)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM