2011-08-10 154 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