2

我正在使用 StyledText 400x100 小部件,它的工作方式类似于程序与用户交互的控制台。

这就是我更新小部件的方式:

private static Shell MainShell = null;

public void createPartControl(Composite parent){
   MainShell = parent.getShell();
}

public static void updateConsole(final String newMessage){
   if(MainShell.isDisposed() || myStyledText.isDisposed() ) return;

   MainShell.getDisplay().syncExec(new Runnable(){
      myStyledText.setText( newMessage + "\n" + myStyledText.getText() );
   });
}

类似于 append(),但这个插入到第一行并插入换行符“\n”。

我正在使用 CycleBarrier 来处理线程。目前它正在运行 300 多个线程,我只允许 10 个线程/周期不会杀死 CPU。

// divide 300/10 because there is an inner for() which runs 10 threads / cycle
for(int n = 0; n < 300/10; n++){

   // allow only 10 threads to work
   final CycleBarrier br = new CycleBarrier(10);

   for(int i = 0; i < 10; i++){
      new Thread(new MyClass(cb).start();
   }

   //waiting for Threads to reach the barrier
   br.await();
}

现在是MyClass类:

public MyClass implements Runnable{
   private CycleBarrier cb;

   public MyClass(CycleBarrier cb){
      this.cb = cb;
   }

   @Override
   public void run(){
      for(int i = 0; i < 256; i++){
         for(int j = 0; j < 256; j++){
            //View is the main class (eclipse RCP) and updateing the widget
            View.updateConsole("matrix["+i+"]["+j+"]");

            // Just an integer which counts the number of the loops
            View.TOTAL_LOOPS++;
         }
      }
      cb.await();
   }
}

这是一个例子。它应该以异步方式(不是按顺序)写入 View 小部件,因为线程没有按顺序到达屏障。

我正在使用 Eclipse RCP (3.8)。

问题

为什么程序在 DEBUG 模式下工作正常?我已经设置了一个断点,我将在其中启动新线程(在内部 for() 中),然后单击 Resume 按钮以逐个启动线程。当我尝试以正常模式(运行或导出)打开时,会出现“泄漏”(我不知道如何命名),控制台中的行数较少。View.TOTAL_LOOPS 总共应该有:

256*256*10*30 = 19660800 // View.TOTAL_LOOPS++; 在我的班级

在正常运行中,它具有动态结果:174614904、17025759 等。在调试模式下,它达到了精确值。

问题:

线程被杀死了吗?

4

1 回答 1

2

它与 SWT 无关。您一次从 10 个线程中增加一个共享变量。这是竞态条件的经典示例。由于++不是原子操作,因此可能会发生以下情况:

int temp = View.TOTAL_LOOPS; // in thread 1
int temp = View.TOTAL_LOOPS; // in thread 2
int temp2 = temp + 1; // in thread 1
View.TOTAL_LOOPS = temp2; // in thread 1
int temp2 = temp + 1; // in thread 2
View.TOTAL_LOOPS = temp2; // in thread 2

NoteView.TOTAL_LOOPS在此之后仅增加 1,如果您一个接一个地启动线程,显然不会发生这种情况。

AtomicInteger如果您只想要一个线程安全的计数器或以其他方式正确同步您的线程,请改用。

于 2013-02-13T20:28:04.150 回答