안녕하세요 자바 기초 스레드를 배우고 있는데 예제에 이해가 안되는 부분이 있어 질문드립니다.

아래의 코드는 아무 키나 누를 때





이런식으로 바가 마젠타색으로 차고

스레드에 의해 바가 점점 줄어드는 코드입니다.


그런데 이상한점이 바가 꽉찬 상태에서 키를 일정시간 눌렀다가 때면

키를 누르고 있지 않음에도 불구하고 계속 fill() 함수가 작동해 바로 바가 줄어드는 것이 아닌

누른 만큼 시간이 지난후 바가 줄어드는데 왜 이런 현상이 일어나는지 설명해주실 고수분 계신가요 ㅜㅜ 





import javax.swing.*; import java.awt.*; import java.awt.event.*; class MyLabel extends JLabel { private int barSize = 0; private int maxBarSize; public MyLabel(int maxBarSize) { this.maxBarSize = maxBarSize; } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.MAGENTA); int width = (int) ( ( (double)( getWidth() ) )/maxBarSize *barSize ); if (width == 0) return; g.fillRect(0, 0, width, this.getHeight()); } synchronized void fill() { System.out.println(barSize); if (barSize == maxBarSize) { try { System.out.println("바가 다 차서 수면"); wait(); //바의 크기가 최대이면, ComsumerThread 의해 바의 크기가 줄어들때 까지 대기 } catch (InterruptedException e) { // TODO Auto-generated catch block return; } } //System.out.println("fill"); barSize++; repaint(); notify(); } synchronized void consume() { if (barSize == 0) { try { System.out.println("바가 0이라서 수면"); wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block return; } } //System.out.println("consume"); barSize--; repaint(); notify(); } } class ComsumerThread extends Thread { private MyLabel bar; public ComsumerThread(MyLabel bar) {this.bar = bar; } @Override public void run() { // TODO Auto-generated method stub while(true) { try { sleep(100); bar.consume(); } catch (InterruptedException e) { // TODO Auto-generated catch block return; } } } } public class TabAndThreadEx extends JFrame { private MyLabel bar = new MyLabel(100); public TabAndThreadEx(String title) { super(title); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container c = getContentPane(); c.setLayout(null); bar.setBackground(Color.orange); bar.setOpaque(true); bar.setLocation(20, 50); bar.setSize(300, 20); c.add(bar); c.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { bar.fill(); } }); setSize(350, 200); setVisible(true); c.setFocusable(true); c.requestFocus(); ComsumerThread th = new ComsumerThread(bar); th.start(); } public static void main(String[] args) { // TODO Auto-generated method stub new TabAndThreadEx("아무키나 빨리 눌러 바 채우기"); } }