我正在尝试编写线程干扰示例。
以下是我的代码:
class Counter {
private int c = 0;
public void increment() {
c++;
}
public void decrement() {
c--;
}
public int value() {
return c;
}
}
假设线程A在大约同一时间调用增量,线程B调用减量。 如何实现这一个。
答案 0 :(得分:2)
无法保证它们如何运行取决于操作系统调度程序。没有什么比这个更好了
Thread a = new ThreadA();
Thread b = new ThreadB();
a.start();
b.start();
答案 1 :(得分:1)
要让两个线程同时开始执行,您可以使用锁存器。 (也就是说,两个线程变为可用以便尽可能靠近地执行。)仍然对于单个递增/递减,每个可能需要多次运行来观察干扰。对于可重复的实验,您可能希望并行地多次调用递增/递减并观察c的最终值。
final Counter counter = new Counter()
final CountDownLatch latch = new CountDownLatch(1);
Thread thread1 = new Thread(new Runnable() {
public void run() {
latch.await();
for (int i = 0; i < 100; i++) {
counter.increment();
}
}}).start():
Thread thread2 = new Thread(new Runnable() {
public void run() {
latch.await();
for (int i = 0; i < 100; i++) {
counter.decrement();
}
}}).start():
Thread.sleep(10);//give thread 2 a timeslice to hit the await
latch.countDown();
System.out.println(counter.value()); //non-zero value indicates interference
答案 2 :(得分:0)
现在,在此示例中,如果您尝试执行并且输出false
显示干扰。
Runnable
都保留 线程本地计数 ,每次调用increment()
和decrement()
时都会增加。因此,如果我们尝试验证值
然后你可以这样说:
value of Counter = invocation of increment() - invocation of decrement()
。
但是当你尝试在执行结束时验证这一点时,你会得到false
。这表明实际的计数器值并不像预期的那样。
public static void main(String[] args) throws InterruptedException
{
Counter c = new Counter();
IncrementingRunnable incRunnable = new IncrementingRunnable(c);
DecrementingRunnable decRunnable = new DecrementingRunnable(c);
Thread tA = new Thread(incRunnable);
Thread tB = new Thread(decRunnable);
tA.start();tB.start();
Thread.sleep(10000);
stop = true;
tA.join();
tB.join();
//verify value
int actualCount = c.c;
int expectedCount = incRunnable.count - decRunnable.count;
System.out.println(actualCount == expectedCount);
}
public static volatile boolean stop = false;
static class IncrementingRunnable implements Runnable{
volatile int count = 0;
private Counter counter;
public IncrementingRunnable(Counter c) {
this.counter = c;
}
@Override
public void run() {
while(!stop){
counter.increment();
count++;
}
}
}
static class DecrementingRunnable implements Runnable{
volatile int count = 0;
private Counter counter;
public DecrementingRunnable(Counter c) {
this.counter = c;
}
@Override
public void run() {
while(!stop){
counter.decrement();
count++;
}
}
}
现在尝试将c
中的原始Counter
更改为AtomicInteger
并再次查看输出。您会发现现在输出为true
。