使用Semaphore运行时java.util.NoSuchElementException

时间:2015-08-07 15:38:31

标签: java multithreading semaphore

我有一个包含10个元素的Queue,我启动了100个线程,其中6个可以同时运行,由Semaphore控制。当每个线程运行时,它会将head元素添加到尾部。但有时我得到这个例外:

java.util.NoSuchElementException
 at java.util.LinkedList.removeFirst(LinkedList.java:270)
 at java.util.LinkedList.remove(LinkedList.java:685)
 at IBM.SemApp$1.run(SemApp.java:27)
 at java.lang.Thread.run(Thread.java:745)
import java.util.LinkedList;    
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.Semaphore;

public class SemApp {
public static void main(String[] args) {

    Queue queueB = new LinkedList<>();
    for (int i = 0; i < 10; i++) {
        queueB.add("Object " + i);
    }

    Runnable limitedCall = new Runnable() {
        final Random rand = new Random();
        final Semaphore available = new Semaphore(6);
        int count = 0;

        public void run() {
            int time = rand.nextInt(15);

            try {
                available.acquire();
                String A = (String) queueB.remove();
                queueB.add(A);
                available.release();
                count++;
                System.out.println(count);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };

    for (int i = 0; i < 100; i++) {
        new Thread(limitedCall).start();
    }
}
}

我做错了什么?

2 个答案:

答案 0 :(得分:2)

问题是LinkedList不是线程安全的结构。

因此,它不应由多个并发线程共享和修改,因为queueB上的更改可能无法正确地“传递”到其他线程。

请尝试使用LinkedBlockingQueue

另外,对AtomicLong使用count也是出于同样的原因:它在多个线程之间共享,您希望避免竞争条件。

答案 1 :(得分:1)

同时在队列上运行多达六个线程意味着修改不安全。