2011-08-10 105 views
0
public void setGifImage(InputStream inputStream) { 
     checkWidget(); 
     if (thread != null) { 
      thread.stopRunning(); 
      try { 
       thread.join(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     ImageLoader loader = new ImageLoader(); 

     try { 
      loader.load(inputStream); 
     } catch (Exception e) { 
      this.image = null; 
      return; 
     } 

     if (loader.data[0] != null){ 
      System.out.println("set to new picture"); 
      this.image = new Image(this.getDisplay(), loader.data[0]); 
     } 

     if (loader.data.length > 1) { 
      System.out.println("start animation"); 
      thread = new GifThread(loader); 
      thread.start(); 
     }else{ 
      System.out.println("paint static picture"); 
     } 

     redraw(); 
    } 

螺紋:
Java線程加入問題

private class GifThread extends Thread { 

     private int imageNumber = 0; 
     private ImageLoader loader = null; 
     private boolean run = true; 

     public GifThread(ImageLoader loader) { 
      this.loader = loader; 
     } 

     public void run() { 
      while (run) { 
       int delayTime = loader.data[imageNumber].delayTime; 
       try { 
        Thread.sleep(delayTime * 10); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       if (!GifCLabel.this.isDisposed()) { 
        // if a asynchronous thread is running, this new runnable will be queued 
        GifCLabel.this.getDisplay().asyncExec(new Runnable() { 
         public void run() { 
          if (!GifCLabel.this.isDisposed()) { 
           imageNumber = imageNumber == loader.data.length - 1 ? 0 : imageNumber + 1; 
           if (!GifCLabel.this.image.isDisposed()) 
            GifCLabel.this.image.dispose(); 
           ImageData nextFrameData = loader.data[imageNumber]; 
           System.out.println("set to frame " + imageNumber); 
           GifCLabel.this.image = new Image(GifCLabel.this.getDisplay(), nextFrameData); 
           GifCLabel.this.redraw(); 
          } else 
           stopRunning(); 
         } 
        }); 
       } else 
        stopRunning(); 
      } 
     } 

     public void stopRunning() { 
      run = false; 
     } 
    } 

輸出:

2011-08-10 03:44:24 DEBUG - 日誌服務Ready! 
2011-08-10 03:44:28 DEBUG - current is null 
2011-08-10 03:44:28 DEBUG - found : [email protected] 
2011-08-10 03:44:28 DEBUG - can go back ? false 
2011-08-10 03:44:28 DEBUG - can go forward ? false 
set to new picture 
start animation 
2011-08-10 03:44:28 DEBUG - 嘗試連接至 - jdbc:mysql://localhost:3306/credit 驅動配置:MySQL 驅動類:[email protected] 連接屬性:{user=root, password=root} 
set to frame 1 
set to frame 2 
set to frame 3 
set to frame 4 
[[email protected], [email protected]] 
set to new picture 
paint static picture 
set to frame 5 

我不知道爲什麼線程的Thread.join後仍然運行()?正如我所知,thread.join()等待線程死亡,但你可以看到輸出的最後一行,死後線程運行...

+0

你確定要加入線程是你看不到的日誌在同一個線程?換句話說,沒有創建額外的線程? (你應該使方法同步) – SJuan76

+0

感謝關心。哪種方法要同步?這也能解決我的問題,因爲馬克斯的答案?雖然我的問題已經解決,但我想了解更多關於線程的知識:D – CaiNiaoCoder

+0

Max和我都認爲你加入的線程不是做這項工作的線程。我的想法可能是您的setGifImage方法正在同時訪問;這是真的,它可能發生一個線程被連接兩次,並創建一個未連接的線程。如果你確定你的方法沒有被同時調用,那麼就不需要改變;你可以在其他地方使它同步。 – SJuan76

回答

3

這裏的問題是,你線程調用getDisplay().asyncExec()基本上發送事件到UI線程來執行打印"set to frame "的Runnable。

更好地使用syncExec()並檢查run Runnable內部的變量狀態。

另一個提示:

  1. 這不是趕InterruptedException,什麼也不做一個好主意。
  2. 呼叫interruptstopRunnable()
  3. 檢查run變量狀態sleep結束。

乾杯, 最大

+0

「檢查Runnable內部運行變量狀態」的工作原理! – CaiNiaoCoder