2015-04-20 29 views
1

我创建了下列程序,它使用相同的线程实例运行两个线程。我初始化了一个计数器,当每个线程运行时,计数器的值应该被执行,最后它应该在控制台中输出。线程运行时计数器的值没有被执行

public class MTThread { 

static int count = 0; 

public static void main(String arg[]){ 

    System.out.println("Main started"); 
    MTThreadInner in1= new MTThreadInner(1,count); 
    MTThreadInner in2= new MTThreadInner(2,count); 

    in1.start(); 

    in2.start(); 
    while (true) { 
     try { 
      in1.join(); 
      in2.join(); 
      break; 
     } 
     catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    System.out.println("Main finished, count = :"+ count); 

}} 

class MTThreadInner extends Thread { 
     int num; int counter; 
     MTThreadInner(int i,int z) { 
      counter=z; 
      num = i; 

     } 

     public void run(){ 
       // TODO Auto-generated constructor stub 
      yield(); 
      System.out.println("This ran Thread "+ num); 
      counter=counter+1; 

     } 


    } 

但是输出总是显示计数为 “0”:

主要开始

此跑线程1

此跑线程2

主要成品,计数=: 0

+1

它应该打印'count = 0'你能解释一下为什么你希望'count'完全改变吗? –

+0

当thread1结束时,该值将增加1,并且在该线程运行两次后,值也会增加,但我认为计数值没有被返回 – Splasher

+0

每个线程都将其自身的本地副本值0并将其递增为1.这不会与'count'共享或在任何地方复制。 –

回答

2

你的输出应该是count = 0不要随意更改此变量。

你要做的就是将这个变量复制到MTThreadInner.counter中的另一个字段中,其中每个线程将其自己的副本更改为1,但这是完全不相关的变量。

你可能期望做的是增加一个共享的线程安全变量。要做到这一点,我建议做一个计数的AtomicInteger

static AtomicInteger count = new AtomicInteger(0); 

这样你就可以在参考复制到相同的共享,线程安全的对象,当您在每个线程中调用counter.incrementAndGet()这将增加该对象。

+0

我没有得到它,因为我是初学者,你可以给我一个代码看起来像 – Splasher

+0

@Splasher的想法,你只需要在我的答案中复制代码并改变'counter' AtomicInteger的类型它都编译。 –

+0

我这样做,它编译,但它显示语句'counter = counter + 1'上的错误 – Splasher

1

我创建了以下程序,它运行两个线程与同一个线程实例。

不,你已经创建了一个通过同一Thread子类的不同实例运行两个线程的程序。

应该执行计数器值,并在最后它应该在控制台中输出。

Thread子类的每个实例都有一个私人counter变量,我敢肯定,这些线程做更新(但你怎么会知道?)。这与静态变量MTThread.count无关,这是您在最后打印的内容。