我正在尝试同步我的 Person
类方法,以便我的静态计数器变量一次被一个线程递减。
public class Person extends Thread {
private static int count = 10;
public void decrement() {
synchronized(Person.class) {
count--;
}
}
public int getCount() {
return count;
}
public void run(){
while( count > 0){
this.decrement();
System.out.print(this.getCount() + ",");
}
}
}
这是我的主课。每个线程将通过同步方法递减到静态计数器,以避免多个线程访问同一资源。
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
Person p3 = new Person();
Person p4 = new Person();
Person p5 = new Person();
p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
}
}
但是当我运行我的程序时,它正在打印重复的计数器值。我做错了什么?
输出:
8,8,7,6,5,4,3,2,1,0
8,7,5,3,1,0,6,8,4,0
最佳答案
原始代码中发生的事情如下:
- 线程一递减计数(计数 -> 9)
- 线程两次递减计数(计数 -> 8)
- 线程三个递减计数(count -> 7)
- 线程四递减计数(count -> 6)
- 线程一输出计数(计数:6)
- 线程两个输出计数(计数:6)
- 线程三个输出计数(计数:6)
- 线程四个输出计数(计数:6)
由于您锁定的是减量,而不是同时锁定减量和输出,因此它看起来会多次减量。
换句话说,不能保证这段代码会连续执行:
this.decrement();
System.out.print(this.getCount() + ",");
这是固定代码。它在递减时返回当前计数值,以便可以返回和打印新值。
public class Person extends Thread {
private static int count = 10;
public int decrement() {
synchronized(Person.class) {
count = count - 1;
return count;
}
}
public int getCount() {
synchronized(Person.class) {
return count;
}
}
public void run(){
while( getCount() > 0){
int count = this.decrement();
System.out.println(count);
}
}
}
不过我会推荐 AtomicInteger 来完成这项任务:
import java.util.concurrent.atomic.AtomicInteger;
public class Person extends Thread {
private static AtomicInteger count = new AtomicInteger(10);
public int decrement() {
return count.decrementAndGet();
}
public void run(){
while(count.get() > 0){
int currentCount = this.decrement();
System.out.print(currentCount + ",");
}
}
}
关于Java:多个线程通过同步方法同时访问变量递减静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36753028/