【问题标题】:How to get static variable properly from multithreading class? [duplicate]如何从多线程类中正确获取静态变量? [复制]
【发布时间】:2019-05-11 09:26:38
【问题描述】:

假设我有这样的代码:


class A extends Thread {
    Thread t = new Thread();
    private static int id = 0;

    A(){
        id++;
        this.t.start();
    }

    private synchronized static int getId() { return id; }

    public void run() { System.out.println(getId()); }
}

public class Test throws InterruptedException {
    public static void main(String[] args) {
        A thread1 = new A();
        A thread2 = new A();
        try {
            thread1.t.join();
            thread2.t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Main thread ends here");
    }
}

我期待这样的输出:


1
2

但是输出是:


2
2

我应该在这里做什么?感谢帮助。问。

【问题讨论】:

  • private static volatile int id = 0;
  • volatile 不够,++ 不是原子的:stackoverflow.com/questions/25168062/why-is-i-not-atomic -> 使用 AtomicInteger
  • 为什么你的Thread 里面有一个Thread?此外,永远不要extends Thread - 这会产生各种奇怪的行为,请使用Runnable。你永远不会启动你的A 实例;你启动了一个内部Thread,它什么都不做。您在 ctor 中增加变量而不是在 run() 方法中。这段代码几乎在所有方面都是错误的 - 请先阅读有关 Java 线程的基本教程。
  • 谢谢,我必须解决。问。
  • 此代码无法编译。 getId 方法在类 Thread 中定义,它返回一个 long,而不是 int。

标签: java multithreading


【解决方案1】:

对于这种情况,您应该使用AtomicInteger 而不是 int,并更改方法。

public class Test
{

    public static void main(String[] args) throws InterruptedException
    {
        final A thread1 = new A();
        final A thread2 = new A();
        try
        {
            thread1.join();
            thread2.join();
        }
        catch (final InterruptedException e)
        {
            e.printStackTrace();
        }
        Thread.sleep(1000);
        System.out.println("Main thread ends here");
    }

    public static class A extends Thread
    {
        private static final AtomicInteger id = new AtomicInteger(0);

        A()
        {
            start();
        }

        private synchronized int getID()
        {
            return id.get();
        }

        @Override
        public synchronized void run()
        {
            id.incrementAndGet();
            System.out.println(getID());
        }
    }
}

【讨论】:

  • 除非您修复混乱的线程情况,否则这并不会真正改变任何事情。无论如何,原始输出将始终为12,因为增量在ctor中同步发生。 (嗯,原来的输出应该是,现在没有输出,因为run 永远不会被执行)
  • 更仔细地阅读代码 - id 只会被主线程改变。该代码没有做任何遥不可及的事情 - 添加 AtomicInteger 不会修复 OP 写的废话。
  • 我修正了打印正确数字的答案
  • @luk2302 我更正了 OP 类,如果您打开问题,我可以发布答案
  • @Spara 你出锁了,OP 已经同意这个问题是重复的——他想要解决的真正问题是原子增量,重复的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-18
  • 2012-01-14
  • 1970-01-01
相关资源
最近更新 更多