Java 如何避免在多线程处理时访问相同的静态计数器
我是多线程新手,这有点让人困惑。如何使用synchronize键给出1 a然后2 b的输出?换句话说,我希望第一个线程访问静态变量x,增加它,然后第二个线程开始Java 如何避免在多线程处理时访问相同的静态计数器,java,multithreading,synchronization,Java,Multithreading,Synchronization,我是多线程新手,这有点让人困惑。如何使用synchronize键给出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.pr
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();
}
}
您可以使用synchronized static方法(在
increment
中,您只是在静态字段上操作,为什么不将其设置为静态呢?)
这种方法在整个类对象上进行同步
如果出于某种原因确实不想使此方法成为静态的,则可以显式地同步类对象上的关键部分
public void increment() {
synchronized(Test1.class) {
x=x+1;
System.out.println(x+" "+ name);
}
}
我建议使用AtomicInteger调用incrementAndGet()。这将自动递增变量,并防止其他线程返回对变量的调用,直到前面的锁被移除,因此递增方法将是:
System.out.println(x.incrementAndGet()+" "+ name);
您也可以像其他用户发布一样使用同步块,但这两种建议的缺点是您牺牲了对锁对象的控制,因为方法上的同步关键字相当于:
synchronized (this) { }
引用类对象并不会使对象保持在类的内部。是希望线程一次运行一个线程,还是线程a先运行实际上很重要?不,我不在乎a是否先运行。我关心的是1和2的输出。实际上我尝试过这个,编译器在大多数时候都给我2-2的输出。谢谢它的工作!但是你能解释一下为什么给出的第一种方法,即同步无效增量不起作用吗?不太确定,但可能是System.out本身?@HusseinJaber第一种方法不是“同步无效增量”,而是“静态同步无效增量”。
static
关键字是这里的重要关键字。AtomicInteger
是一类非常狭窄的问题的解决方案。OP可能首先应该了解保护数据免受冲突(即互斥)的更一般的方法。
synchronized (this) { }