문제

내가 있는 클래스에서 개체 BlockingQueue 과 프로세스들에 의해 호출 take() 하는 작업을 반복했습니다.어떤 시점에서 난 더 이상 물체에 추가될 것입니다.나는 어떻게 인터럽트 take() 방법을 중단이 막고 있는가?

여기에는 클래스 프로세스 개체:

public class MyObjHandler implements Runnable {

  private final BlockingQueue<MyObj> queue;

  public class MyObjHandler(BlockingQueue queue) {
    this.queue = queue;
  }

  public void run() {
    try {
      while (true) {
        MyObj obj = queue.take();
        // process obj here
        // ...
      }
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    }
  }
}

그리고 여기에는 방법을 사용하는 이 클래스는 프로세스 개체:

public void testHandler() {

  BlockingQueue<MyObj> queue = new ArrayBlockingQueue<MyObj>(100);  

  MyObjectHandler  handler = new MyObjectHandler(queue);
  new Thread(handler).start();

  // get objects for handler to process
  for (Iterator<MyObj> i = getMyObjIterator(); i.hasNext(); ) {
    queue.put(i.next());
  }

  // what code should go here to tell the handler
  // to stop waiting for more objects?
}
도움이 되었습니까?

해결책

스레드를 방해하는 것이 옵션이 아닌 경우, 다른 하나는 큐에 "마커"또는 "명령"객체를 MyObjhandler로 인식하고 루프에서 나누는 것입니다.

다른 팁

BlockingQueue<MyObj> queue = new ArrayBlockingQueue<MyObj>(100);
MyObjectHandler handler = new MyObjectHandler(queue);
Thread thread = new Thread(handler);
thread.start();
for (Iterator<MyObj> i = getMyObjIterator(); i.hasNext(); ) {
  queue.put(i.next());
}
thread.interrupt();

그러나이 작업을 수행하면 대기열에 여전히 항목이있는 동안 스레드가 중단 될 수 있으며 처리되기를 기다리고 있습니다. 사용을 고려하고 싶을 수도 있습니다 poll 대신에 take, 이는 처리 스레드가 타임 아웃을 허용하고 새로운 입력없이 잠시 기다렸을 때 종료 될 수 있습니다.

매우 늦었지만 희망이 다른로 내가 직면한 문제 및 이용 poll 접근 방식에 의해 제안 에릭슨의 위 으로 약간의 변화

class MyObjHandler implements Runnable 
{
    private final BlockingQueue<MyObj> queue;
    public volatile boolean Finished;  //VOLATILE GUARANTEES UPDATED VALUE VISIBLE TO ALL
    public MyObjHandler(BlockingQueue queue) 
    {
        this.queue = queue;
        Finished = false;
    }
    @Override
    public void run() 
    {        
        while (true) 
        {
            try 
            {
                MyObj obj = queue.poll(100, TimeUnit.MILLISECONDS);
                if(obj!= null)//Checking if job is to be processed then processing it first and then checking for return
                {
                    // process obj here
                    // ...
                }
                if(Finished && queue.isEmpty())
                    return;

            } 
            catch (InterruptedException e) 
            {                   
                return;
            }
        }
    }
}

public void testHandler() 
{
    BlockingQueue<MyObj> queue = new ArrayBlockingQueue<MyObj>(100); 

    MyObjHandler  handler = new MyObjHandler(queue);
    new Thread(handler).start();

    // get objects for handler to process
    for (Iterator<MyObj> i = getMyObjIterator(); i.hasNext(); )
    {
        queue.put(i.next());
    }

    // what code should go here to tell the handler to stop waiting for more objects?
    handler.Finished = true; //THIS TELLS HIM
    //If you need you can wait for the termination otherwise remove join
    myThread.join();
}

이는 해결 모두 문제

  1. 플래그 BlockingQueue 그래서 그것을 알고 있지 않기 위해 더 많은 요소
  2. 하지 않았다 사이에서 중단되도록 처리 블록을 종료한 경우에만 모든 항목에서 큐 처리하고 있는 남은 항목을 추가할

스레드를 방해합니다.

thread.interrupt()

또는 방해하지 마십시오.

    public class MyQueue<T> extends ArrayBlockingQueue<T> {

        private static final long serialVersionUID = 1L;
        private boolean done = false;

        public ParserQueue(int capacity) {  super(capacity); }

        public void done() { done = true; }

        public boolean isDone() { return done; }

        /**
         * May return null if producer ends the production after consumer 
         * has entered the element-await state.
         */
        public T take() throws InterruptedException {
            T el;
            while ((el = super.poll()) == null && !done) {
                synchronized (this) {
                    wait();
                }
            }

            return el;
        }
    }
  1. 프로듀서가 대기열에 객체를 넣으면 전화하십시오 queue.notify(), 종료되면 전화하십시오 queue.done()
  2. 루프 while (! queue.isdone () ||! queue.isempty ())
  3. null의 테스트 () 반환 값을 테스트합니다
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top