2016-06-30 3 views
0

私はSpringXDでの作業にReentrantLockを追加しようとしていますが、時にはスレッド間に中断があるようです。ReentrantLockがSpringXDで動作しない理由

例えば、私はこれらのコードを持っている:

public class LoadGenerator extends MessageProducerSupport { 

private final AtomicBoolean running = new AtomicBoolean(false); 
private ExecutorService executorService; 

Logger logger = LoggerFactory.getLogger(LoadGenerator.class); 

public LoadGenerator(){} 

@Override 
protected void doStart() { 
    executorService = Executors.newFixedThreadPool(2); 
    if (running.compareAndSet(false, true)) { 
     for (int x = 0; x < 10; x++) { 
      executorService.submit(new Producer(Integer.toString(x))); 
     } 
    } 
} 

@Override 
protected void doStop() { 
    if (running.compareAndSet(true, false)) { 
     executorService.shutdown(); 
    } 
} 

protected class Producer implements Runnable { 
    String prefix; 
    Lock lock = new ReentrantLock(); 

    public Producer(String prefix) { 
     this.prefix = prefix; 
    } 

    private void send() { 
     lock.lock(); 
     try{ 
      for(int i = 0; i < 10; i++){ 
       System.out.println(Thread.currentThread().getName() + " " + i); 
      } 
     }finally{ 
      lock.unlock(); 
     } 
    } 

    public void run() { 
     send(); 
    } 
} 
} 

私はそれから期待したもの、すべてのスレッドでの順序と順序を中断すべきではない

pool-604-thread-1 0 
pool-604-thread-1 1 
pool-604-thread-1 2 
pool-604-thread-1 3 
pool-604-thread-1 4 
pool-604-thread-1 5 
pool-604-thread-1 6 
pool-604-thread-1 7 
pool-604-thread-1 8 
pool-604-thread-1 9 
pool-604-thread-2 0 
pool-604-thread-2 1 
pool-604-thread-2 2 
pool-604-thread-2 3 
pool-604-thread-2 4 
pool-604-thread-2 5 
pool-604-thread-2 6 
pool-604-thread-2 7 
pool-604-thread-2 8 
pool-604-thread-2 9 
... 

ようなリストですが、実際には次のような中断があることがあります:

pool-604-thread-1 0 
pool-604-thread-2 0 
pool-604-thread-2 1 
pool-604-thread-2 2 
pool-604-thread-1 1 
pool-604-thread-1 2 
pool-604-thread-1 3 

何が問題なのですか?ロックはEclipse上のlocalhostでうまく動いています。

SpringXDは分散システムなのですか?しかし、私は自分のxdadminに1つのxdcontaierしか接続していません。

ありがとうございました。あなたはすべての新しいRunnableでそれを作成しないで、あなたのReentrantLockを渡す必要があり

答えて

3

のように、プロデューサーは、1 ReentrantLockを共有する必要があります。

@Override 
protected void doStart() { 
    executorService = Executors.newFixedThreadPool(2); 
    Lock lock = new ReentrantLock(); // create a share lock to lock in multi threads 
    if (running.compareAndSet(false, true)) { 
     for (int x = 0; x < 10; x++) { 
      executorService.submit(new Producer(Integer.toString(x), lock)); //pass this lock to every producer 
     } 
    } 
} 
protected class Producer implements Runnable { 
    String prefix; 
    final Lock lock; 

    public Producer(String prefix, Lock lock) { 
     this.prefix = prefix; 
     this.lock = lock; 
    } 

    private void send() { 
     lock.lock(); 
     try{ 
      for(int i = 0; i < 10; i++){ 
       System.out.println(Thread.currentThread().getName() + " " + i); 
      } 
     }finally{ 
      lock.unlock(); 
     } 
    } 

    public void run() { 
     send(); 
    } 
} 
+0

これは厄介な...男、私のミスです...私は彼らを知っていましたロックを共有する必要があります...私はちょうど...私はそれを投稿する前にそれを確認する必要があります...しかし、とにかく、ありがとう... – cinqS

関連する問題