【问题标题】:counter value is not being implemented when threads run线程运行时未实现计数器值
【发布时间】:2015-04-20 18:15:17
【问题描述】:

我创建了以下程序,它运行具有相同线程实例的两个线程。我已经初始化了一个计数器,当每个线程运行时,应该实现计数器值,最后它应该在控制台中输出。

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

主要完成,count = :0

【问题讨论】:

  • 它应该打印count = 0 你能解释一下为什么你期望count 会改变吗?
  • 随着thread1结束,值增加1,线程两次运行后,值也增加,但我认为count值没有返回
  • 每个线程都获取它自己的值 0 的本地副本并将其递增到 1。这不会与 count 共享或复制到任何地方。

标签: java multithreading count


【解决方案1】:

输出应为count = 0,因为您无需在任何地方更改此变量。

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

您可能期望做的是增加一个共享的、线程安全的变量。为此,我建议将 count 设为 AtomicInteger

static AtomicInteger count = new AtomicInteger(0);

这样您可以将 reference 复制到同一个共享的线程安全对象,当您在每个线程中调用 counter.incrementAndGet() 时,它会增加该对象。

【讨论】:

  • 我是初学者,不明白,你能告诉我代码的样子吗
  • @Splasher 您只需要复制我的答案中的代码并更改counter AtomicInteger 的类型,以便全部编译。
  • 我这样做了,它编译了,但是它在语句 'counter=counter+1' 上显示错误
  • @Splasher 这是您使用counter.incrementAndGet(); 的地方。
  • 非常感谢您的帮助
【解决方案2】:

我创建了以下程序,它运行具有相同线程实例的两个线程。

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

计数器值应该被实现,并在最后它应该在控制台中输出。

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

【讨论】:

    猜你喜欢
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多