java - 等待通知多线程生产者消费者问题

标签 java multithreading wait producer-consumer notify

我正在研究一个基本的线程生产者消费者问题。

现在在我的这段代码中我假设的是 1)线程最初将进入等待状态,当任何任务到来时,其中一个任务将收到通知,它将处理该任务,然后再次等待,但我的线程将突然进入可运行状态。我的理解正确吗?

public static void main(String[] args) {
    AsyncTaskExecutorImpl executorImpl = new AsyncTaskExecutorImpl(10, 5);

    for (int i = 0; i < 200; i++) {

        Runnable task = new createTask();
        System.out.println("Added task no" + i);
        executorImpl.execute(task, 10);
    }
}



import java.util.concurrent.ArrayBlockingQueue;

public class MyArrayBlockingQueue<T> {
private volatile ArrayBlockingQueue<Runnable> internalTaskQueue = new ArrayBlockingQueue<Runnable>(
        10);


public boolean isEmpty() {
    synchronized (this) {
        return internalTaskQueue.isEmpty();
    }
}

public void add(Runnable paramRunnable) throws InterruptedException {
    synchronized (this.internalTaskQueue) {
        this.internalTaskQueue.put(paramRunnable);
        this.internalTaskQueue.notifyAll();

    }

    for (Thread t : Thread.getAllStackTraces().keySet()) {
        if (t.getName().startsWith("T") || t.getName().startsWith("M")) {
            System.out.println(t.getName() + "----" + t.getState());
        }
    }

}

public Runnable poll() {

    Runnable task = null;
    try {
        synchronized (this.internalTaskQueue) {
            while (this.internalTaskQueue.isEmpty()) {

                this.internalTaskQueue.wait();

            }
            task = this.internalTaskQueue.poll();
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return task;
}
}`
 import java.util.concurrent.Callable;
 import java.util.concurrent.Future;

 import org.springframework.core.task.AsyncTaskExecutor;

 public class AsyncTaskExecutorImpl implements AsyncTaskExecutor {

private  MyArrayBlockingQueue<Runnable> taskQueue= new MyArrayBlockingQueue<Runnable>();

// Here we are creating a Thread pool of number of threads required
public AsyncTaskExecutorImpl(int no_of_threads, int taskQueueSize) {

    for (int i = 0; i < no_of_threads; i++) {
        IndividualThread thread = new IndividualThread(this.taskQueue);
        thread.start();
    }

    for (Thread t : Thread.getAllStackTraces().keySet()) {
        if (t.getName().startsWith("T") || t.getName().startsWith("M")) {
            System.out.println(t.getName() + "----" + t.getState());
        }
    }
}

@Override
public void execute(Runnable paramRunnable, long paramLong) {
    if (paramRunnable instanceof Runnable) {

        // pick any thread from the threadpool and then execute that
        try {
            this.taskQueue.add(paramRunnable);

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}`
class CreateTask implements Runnable {
@Override
public void run() {

    System.out.println(Thread.currentThread().getName() + "got the task");

}

最佳答案

NotifyAll 将“唤醒”所有等待线程。但逻辑上应该是可以的,因为它们随后会竞争进入“同步” block ,第一个获得访问权限的线程会发现“非空”,提取数据,退出“同步” block 。
然后其他一些线程将进入同步块(synchronized block),但到那时它将看到“空”并立即返回等待(当然,除非有多个“添加”操作,在这种情况下,多个线程将看到“非空”)。换句话说,如果你的自旋锁设计正确,线程将在短暂的几分之一秒内变为可运行状态。

还有“Object.notify”只能唤醒一个线程,但据我所知,它对于像您这样的自旋锁来说被认为是不安全的。

关于java - 等待通知多线程生产者消费者问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31231663/

相关文章:

java - XX :MaxPermSize max value in 32bit

java - Eclipse 调试器在每次重新发布时暂停

java - 为什么这些同步方法不断给我不同的输出?

java - 调用future.cancel()时如何避免困惑?

java - 如何确保写入整数数组的可见性

java - 等待线程循环完成

c# - Azure 移动服务客户端 - 在多个 InsertAsync 任务上使用 WaitAll

java - 不同键码之间的转换

JavaScript 小部件必须等待 AngularJS 变量值

java - 如何 @Inject 到主类 - Java - Play Framework