2015-07-05 3 views
1

Я работал над основной проблемой потребителей нитей.Ждите уведомления о проблеме многопоточности производителя.

сейчас в моем этом коде, что я предполагаю, является 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"); 

} 
+0

Что это за строка 'new createTask();'? Можно ли начинать имена классов с нижнего регистра? – selalerer

+0

@selalerer да его класс любезно игнорирует эту ошибку опечатки. Я добавил класс CreateTask. –

+0

@AnilSharma в чем ваш вопрос? Есть ли ошибка в коде или вы хотите понять, как это работает? – Dien

ответ

0

NotifyAll будет «просыпаться» все ожидающие темы. Но это должно быть логически нормально, потому что тогда они будут конкурировать, чтобы попасть в «синхронизированный» блок, первый поток, который получает доступ, найдет «не пусто», вытащит данные, выйду из «синхронизированного» блока.
Тогда какой-то другой поток попадет в синхронизированный блок, но к тому времени он увидит 'empty' & сразу же вернуться к ожиданию (если не было нескольких действий «добавить», конечно, и в этом случае несколько потоков увидели бы «нет» пустой "). Другими словами, если ваш спиновый замок правильно спроектирован, потоки станут Runnable на короткую долю секунды.

Существует также объект Object.notify, который просветит только один поток, но AFAIK считается небезопасным для спин-замков, таких как ваш.

+1

'Object.notify()' существует по какой-то причине, и это безопасно использовать, если вы используете его так, как он был предназначен. Большинство вопросов о 'wait()' и 'notify()' на этой доске исходят от людей, которые не понимают, что 'wait()' и 'notify()' являются примитивами _low level_, которые предназначены для использования в очень специфический рисунок. Большинство людей, которые пишут вызовы 'wait()' и 'notify()', повторно изобретают классы более высокого уровня, которые уже давно доступны из пакета java.util.concurrent и из сторонних библиотек. –

+0

зная внутренние детали чего-то и пытаясь построить что-то с нуля, увеличивает наше понимание этой вещи. Я не согласен с утверждением ура. Мы должны повторно использовать код, но мы не должны скрываться за уже разработанной логикой. :) Не должно быть никаких сомнений в том, что наши руки грязные. –

Смежные вопросы