2011-12-27 3 views
1

백엔드 메시지가 올 때마다 JList에이를 추가하고 fireIntervalAdded를 사용하여 JList를 새로 고칩니다. 문제는 1 초에 20 개의 메시지가 도착할 수 있으며 각 메시지가 fireIntervalAdded를 호출한다는 것입니다. 내가 뭘하고 싶은지 List에 모든 메시지를 쌓고 JList에 하나의 큰 데이터 스택을 보냅니다. 현재 솔루션이 작동하지 않는 것처럼 보이지만 항상 하나의 큰 스택 대신 하나의 메시지를 보냅니다.들어오는 데이터를 스택하는 방법

private class StackingListener implements MessageListener { 
    private List<Message> messages = new LinkedList<Message>(); 
    private int waiting = 0; 
    @Override 
    public void messageReceived(MessageEvent event) { 
     stackData(event.getData()); 
    } 

    private void stackData(Message data) { 
     messages.add(data); 
     if (waiting <= 0) { 
      waiting = 3; 
      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        while(--waiting > 0) { 
         try { 
          Thread.sleep(500); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } 
        } 
        List<Message> list = new ArrayList<Message>(messages); 
        messages.clear(); 
        logger.info("Adding list with size of " + list.size()); 
        controller.getListModel().addFullElements(list); 
       } 
      }).run(); 
     } else { 
      waiting = 3; 
     } 
    } 
} 

제가 잘못 생각한 것 같습니다. 이 코드의 개념은 스레드가 잠자는 동안 메시지를 쌓아 올리는 것입니다. 그러나 Thread.sleep처럼 현재 스레드뿐만 아니라 모든 것을 중지합니다.

감사

+0

안녕하세요, 왜이 모든 대기를해야합니까? 들어오는 메시지를 messageReceived 이벤트의 목록에 쌓아 둘 수 없습니까? 다중 스레드 응용 프로그램을 사용하는 경우 동기화 된 잠금을 추가하여 데이터의 일관성을 보장하는 것이 좋습니다. – Felipe

답변

3

당신은 단지 현재의 thread의 run() 메소드를 호출 Thread.run()를 사용하고 있습니다. 당신이 쓰려고했던 것은 Thread.start()가 쓰레드를 생성하고 그 새로운 쓰레드에서 run()을 호출하는 것이었다.

그러나이 코드는 전혀 구조화되지 않습니다. 나는 더 단순한 apporach가 큐를 사용하는 것이라고 믿는다.

class StackingListener implements MessageListener, Runnable { 
    private final BlockingQueue<Message> messages = new LinkedBlockingDeque<Message>(); 
    private final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); { 
     service.scheduleAtFixedRate(this, 500, 500, TimeUnit.MILLISECONDS); 
    } 

    @Override 
    public void messageReceived(MessageEvent event) { 
     messages.add(event.getData()); 
    } 

    @Override 
    public void run() { 
     final List<Message> list = new ArrayList<Message>(); 
     messages.drainTo(list); 

     logger.info("Adding list with size of " + list.size()); 
     // add to the GUI component in a thread safe manner. 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       controller.getListModel().addFullElements(list); 
      } 
     }); 
    } 

    public void stop() { 
     service.shutdown(); 
    } 
} 
+0

대단히 감사합니다! 나는 몇 시간 동안 나의 코드를 수정 해 왔고 그렇게 명백한 실수를 볼 수 없었다. – Keynash

+0

와우, 고마워요! – Keynash

+0

잘하면이 수정 및 제어 (및 스레드 안전) 구조를 쉽게 볼 수 있습니다. –

관련 문제