简体   繁体   English

等待通知多线程生产者使用者问题

[英]Wait notify multithreading producer consumer issue

I was working on a basic thread-producer consumer problem. 我正在研究一个基本的线程生产者消费者问题。

now in my this code what i am assuming is 1) The threads will go to wait state initially and the moment any task comes one of the tasks will be notified and it will process that task and then again wait but my threads are going to runnable states abruptly. 现在在我的代码中,我假设的是1)线程最初将进入等待状态,并且当任何任务出现时,将通知该任务中的一个,它将处理该任务,然后再次等待,但是我的线程将可运行国家突然。 Is my understanding correct? 我的理解正确吗?

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 would "wake up" all waiting threads. NotifyAll将“唤醒”所有等待的线程。 But it should be logically ok because they would then compete to get into 'sychronized' block , the 1st thread that gets access will find 'not empty', pull the data, exit the 'synchornized' block. 但这在逻辑上应该没问题,因为它们随后将竞争进入“同步”块,获得访问权限的第一个线程将发现“非空”,提取数据,退出“ synchornized”块。
Then some other thread would get into the synchronized block, but by then it would see 'empty' & immediately get back to waiting (unless there were several 'add' actions, of course, in which case several threads would see 'not empty'). 然后,其他一些线程将进入同步块,但届时它将看到“空”并立即回到等待状态(除非有多个“添加”操作,当然,在这种情况下,多个线程将看到“非空” )。 In other words, if your spin lock is correctly designed, threads would become Runnable for a brief fraction of a second. 换句话说,如果您的自旋锁设计正确,线程将在短短几分之一秒内变为可运行状态。

There's also 'Object.notify' that would wake up only one thread, but AFAIK it's considered unsafe for spin-locks such as yours. 还有“ Object.notify”,它只能唤醒一个线程,但是AFAIK对于像您这样的自旋锁来说是不安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM