java 同步方法不工作?
我正在试验 Java 多线程,使用同步方法与原子变量(java.util.concurrent.atomic 包)进行比较。
下面是这些类:
// Interface ICounter.java
public interface ICounter {
public void increment();
public void decrement();
public int value();
}
// Class Counter.java
public class Counter implements ICounter {
private int c = 0;
@Override
public void increment() {
c++;
}
@Override
public void decrement() {
c--;
}
@Override
public int value() {
return c;
}
}
// Class AtomicCounter.java
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicCounter implements ICounter {
private AtomicInteger c = new AtomicInteger(0);
@Override
public void increment() {
c.incrementAndGet();
}
@Override
public void decrement() {
c.decrementAndGet();
}
@Override
public int value() {
return c.get();
}
public long getIncrement() {
return c.incrementAndGet();
}
}
// Class MainProg.java
public class MainProg {
public static void main(String args[]) {
ICounter counter = new AtomicCounter();
//ICounter counter = new SynchronizedCounter();
Thread thread1 = new Thread(new CountRunner(counter));
Thread thread2 = new Thread(new CountRunner(counter));
thread1.start();
thread2.start();
}
}
class CountRunner implements Runnable {
private ICounter counter;
public CountRunner(ICounter counter) {
this.counter = counter;
}
public void run() {
while (true) {
counter.increment();
System.out.println(Thread.currentThread().getName() + " count=" + counter.value());
System.out.println("-------------------");
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
运行 Atomic 或 Synchronized 的结果并不表明变量整数是线程安全的,例如:
Thread-0 count=1
-------------------
Thread-1 count=2
-------------------
Thread-0 count=3
-------------------
Thread-1 count=4
-------------------
Thread-0 count=5
-------------------
Thread-1 count=6
-------------------
Thread-0 count=7
-------------------
Thread-1 count=8
-------------------
Thread-0 count=10
-------------------
Thread-1 count=10
-------------------
从结果中,最后 2 行显示 2 个线程正在访问整数变量的相同值柜台类。 也许我在这里遗漏了一些东西?
谢谢!
I'm experimenting Java Multi-Threading using synchronization on method comparing with Atomic variables (java.util.concurrent.atomic package).
Below are the classes:
// Interface ICounter.java
public interface ICounter {
public void increment();
public void decrement();
public int value();
}
// Class Counter.java
public class Counter implements ICounter {
private int c = 0;
@Override
public void increment() {
c++;
}
@Override
public void decrement() {
c--;
}
@Override
public int value() {
return c;
}
}
// Class AtomicCounter.java
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicCounter implements ICounter {
private AtomicInteger c = new AtomicInteger(0);
@Override
public void increment() {
c.incrementAndGet();
}
@Override
public void decrement() {
c.decrementAndGet();
}
@Override
public int value() {
return c.get();
}
public long getIncrement() {
return c.incrementAndGet();
}
}
// Class MainProg.java
public class MainProg {
public static void main(String args[]) {
ICounter counter = new AtomicCounter();
//ICounter counter = new SynchronizedCounter();
Thread thread1 = new Thread(new CountRunner(counter));
Thread thread2 = new Thread(new CountRunner(counter));
thread1.start();
thread2.start();
}
}
class CountRunner implements Runnable {
private ICounter counter;
public CountRunner(ICounter counter) {
this.counter = counter;
}
public void run() {
while (true) {
counter.increment();
System.out.println(Thread.currentThread().getName() + " count=" + counter.value());
System.out.println("-------------------");
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
The results from running either the Atomic or Synchronized do not show that the variable integer is thread-safe, e.g.:
Thread-0 count=1
-------------------
Thread-1 count=2
-------------------
Thread-0 count=3
-------------------
Thread-1 count=4
-------------------
Thread-0 count=5
-------------------
Thread-1 count=6
-------------------
Thread-0 count=7
-------------------
Thread-1 count=8
-------------------
Thread-0 count=10
-------------------
Thread-1 count=10
-------------------
From the results, the last 2 lines show the 2 threads were accessing the same value of integer variable of the counter class.
Perhaps I am missing something here?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您在一个步骤中递增该值,然后在另一步骤中获取该值。虽然下面的 AtomicInteger 类保证每个步骤都是原子的,但进行两个单独的操作的事实使得您在 print 语句中看到的值受到执行顺序的影响线程。
为了能够准确显示给定线程更新的值,您需要在单个操作中更新并获取结果值,您的
getIncrement()
方法就是这样做的。将为您提供预期结果的代码如下所示:You're incrementing the value in one step, then getting the value in another step. While each of these individual steps is guaranteed to be atomic by the underling
AtomicInteger
class, the fact that you make two separate operations leaves the value you see in your print statement at the mercy of the order of execution of the threads.To be able to accurately display the value updated by a given thread, you need to both update and get the resulting value in a single operation, which your
getIncrement()
method does. The code which would give you the expected results would look like this:因为您的 counter.increment() 和 System.out.println 不是一个原子操作。
because your
counter.increment()
andSystem.out.println
is not one atomic action.您错过的是您的
AtomicCounter
类确实正常工作,并且观察到的行为发生是因为线程在.increment()
和.value( 的调用之间切换)
:What you missed is that your
AtomicCounter
class does work correctly, and the observed behaviour occurs becase the threads switched between the call to.increment()
and.value()
: