有时候变量总数将等于运行时的其他东西而不是50005000它总是很短,如50005001,有时为什么这种情况发生时不应该同步(这)创建一个只能更新一次的锁锁是由线程释放的吗?
import java.util.concurrent.atomic.AtomicLong;
public class CurrentThread {
public static AtomicLong c = new AtomicLong(0L);
public static AtomicLong total = new AtomicLong(0L);
public static void main(String[] args) {
Thread t = Thread.currentThread();
System.out.println(t);
t.setName("My Thread");
System.out.println(t);
for (int x = 0; x < 10; x++) {
System.out.println("Instance " + x);
new Thread(new Updater(x, "Thread: " + String.valueOf(x))).start();
}
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
}
}
class Updater implements Runnable {
public int na;
private String threadName;
public Updater(int n, String threadName) {
this.na = n;
this.threadName = threadName;
}
@Override
public void run() {
this.updateCount();
if(CurrentThread.total.get() == 50005000) {
System.out.println("Passed");
}
else {
System.out.println("Failed");
}
}
public void updateCount() {
while (CurrentThread.c.get() < 10000) {
synchronized(this) {
CurrentThread.c.getAndIncrement();
CurrentThread.total.addAndGet(CurrentThread.c.get());
System.out.println(this.threadName + " " + String.valueOf(CurrentThread.c.get()) + " " + CurrentThread.total.get() + " " + System.nanoTime());
}
}
}
}
答案 0 :(得分:4)
您在this
上进行同步,因为每个线程都有一个不同的Runnable
实例,所以它实际上根本没有同步。
对所有Updater
个实例之间共享的内容进行同步,例如: Updater.class
。
但是请注意,AtomicLong
上的同步有点代码味道 - 它本来就意味着原子地做事。
您可以改为使用compareAndSet
,并避免完全同步,例如:
while (CurrentThread.c.get() < 10000) {
while (true) {
long currValue = CurrentThread.c.get();
if (currValue >= 10000) break;
long newValue = currValue + 1;
// Only sets c to newValue if its value is still currValue.
if (CurrentThread.c.compareAndSet(currValue, newValue)) {
long total = CurrentThread.total.addAndGet(newValue);
System.out.println(
this.threadName + " " + newValue + " " + total + " " + System.nanoTime());
break;
}
}
}
请注意,这会使用&#34;已知&#34;值,例如newValue
和total
,而不是从AtomicLong
再次获取它们。