簡體   English   中英

等待通知多線程生產者使用者問題

[英]Wait notify multithreading producer consumer issue

我正在研究一個基本的線程生產者消費者問題。

現在在我的代碼中,我假設的是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將“喚醒”所有等待的線程。 但這在邏輯上應該沒問題,因為它們隨后將競爭進入“同步”塊,獲得訪問權限的第一個線程將發現“非空”,提取數據,退出“ synchornized”塊。
然后,其他一些線程將進入同步塊,但屆時它將看到“空”並立即回到等待狀態(除非有多個“添加”操作,當然,在這種情況下,多個線程將看到“非空” )。 換句話說,如果您的自旋鎖設計正確,線程將在短短幾分之一秒內變為可運行狀態。

還有“ Object.notify”,它只能喚醒一個線程,但是AFAIK對於像您這樣的自旋鎖來說是不安全的。

暫無
暫無

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

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