如何避免在多线程时访​​问相同的静态计数器

How to avoid accessing the same static counter while multithreading

我是多线程的新手,有点困惑。我如何使用同步键给出输出: 1 a 然后 2 b ?换句话说,我希望第一个线程访问静态变量 x,递增它,然后启动第二个线程。

public class Test1 extends Thread{
    static int x=0;
    String name;

    Test1(String n){ name=n;}
    public void increment() {
        x=x+1;
        System.out.println(x+" "+ name);
    }

    public void run() {
        this.increment();
    }   
}
public class Main {
    public static void main(String args[]) {
        Test1 a= new Test1("a");
        Test1 b= new Test1("b");
        a.start();
        b.start();
    }
}

您可以使用同步静态方法(在 increment 中,无论如何您只是在静态字段上操作,所以为什么不将其设为静态?)。

public static synchronized void increment() {
    x=x+1;
    System.out.println(x+" "+ name);
}

这种方法是在整个class对象上同步的。

如果出于某种原因你真的不想让这个方法静态你可以明确地同步class对象

上的关键部分
public void increment() {
    synchronized(Test1.class) {
        x=x+1;
        System.out.println(x+" "+ name);
    }
}

我建议使用 AtomicInteger 调用 incrementAndGet()。这将自动增加变量并防止其他线程返回对该变量的调用,直到删除前面的锁,因此您的增量方法将是:

System.out.println(x.incrementAndGet()+" "+ name);

您也可以像其他用户发布的那样使用 synchronized 块,但这两个建议的缺点是您牺牲了对锁对象的控制,因为方法上的 synchronized 关键字等同于:

synchronized (this) { }

并且引用 class 对象不会将对象保留在 class 内部。