Java 个线程(竞争条件)
Java Threads (Race Condition)
我对下面这段代码有疑问。在这里,我希望静态变量 'a' 和 'b' 都出现竞争条件,并且希望这两个变量的输出都小于 1000。但是,当我执行时没有观察到预期的行为下面的代码如图所示,即 b 的输出始终为 1000。但是,当我取消注释标有箭头的行并执行下面的代码时,会观察到两个变量的竞争条件,即两个变量的输出 'a' 和 'b' 小于 1000。需要相同的帮助。如果我错过或忽略了线程的任何基本或基本概念,请原谅我,因为我仍然是 java 线程的新手 !!!
public class SampleRace {
public static void main(String[] args) {
// TODO Auto-generated method stub
SampleRace1 a = new SampleRace1();
SampleRace1 b = new SampleRace1();
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println(SamapleLoop.a); // <---------------------
System.out.println(SampleRace1.b);
}
}
class SamapleLoop {
public static int a = 0;
public static void loop() {
a++;
}
}
class SampleRace1 implements Runnable {
public static int b = 0;
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 1; i <= 500; i++) {
//SamapleLoop.loop(); // <------------------------
b++;
}
}
}
尝试将 500 增加到 500.000.000,或在循环内执行更复杂的操作。线程 a
有可能 运行 在线程 b
甚至启动之前完成 - 所以它们最终 运行 按顺序而不是并行。
您也可以每隔几个周期调用一次 Thread.yield
以放弃您的时间片并让另一个线程 运行。
如果你愿意,我可以建议你可以处理的更合适的比赛条件
import java.util.concurrent.atomic.AtomicInteger;
/*
* author: Atom Karinca
*/
/*
* Run this program multiple times to see the output.
* How does the result vary? Why does that happen?
*
*/
class Racer extends Thread {
private static final int NUM_ITERS = 1000000;
public void run() {
for(int j = 0; j < NUM_ITERS; j++) {
RaceCondition.sum();
}
}
}
public class RaceCondition {
public static long sum = 0;
// What happens when you make this method "synchronized"?
// Do you still see the bug?
//synchronized
public static void sum() {
sum = sum + 1;
}
public static void main(String[] args) throws InterruptedException {
Racer leftAdder = new Racer();
Racer rightAdder = new Racer();
leftAdder.start();
rightAdder.start();
// wait for the threads to finish
leftAdder.join();
rightAdder.join();
System.out.println("Sum: " + sum);
}
}
我对下面这段代码有疑问。在这里,我希望静态变量 'a' 和 'b' 都出现竞争条件,并且希望这两个变量的输出都小于 1000。但是,当我执行时没有观察到预期的行为下面的代码如图所示,即 b 的输出始终为 1000。但是,当我取消注释标有箭头的行并执行下面的代码时,会观察到两个变量的竞争条件,即两个变量的输出 'a' 和 'b' 小于 1000。需要相同的帮助。如果我错过或忽略了线程的任何基本或基本概念,请原谅我,因为我仍然是 java 线程的新手 !!!
public class SampleRace {
public static void main(String[] args) {
// TODO Auto-generated method stub
SampleRace1 a = new SampleRace1();
SampleRace1 b = new SampleRace1();
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println(SamapleLoop.a); // <---------------------
System.out.println(SampleRace1.b);
}
}
class SamapleLoop {
public static int a = 0;
public static void loop() {
a++;
}
}
class SampleRace1 implements Runnable {
public static int b = 0;
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 1; i <= 500; i++) {
//SamapleLoop.loop(); // <------------------------
b++;
}
}
}
尝试将 500 增加到 500.000.000,或在循环内执行更复杂的操作。线程 a
有可能 运行 在线程 b
甚至启动之前完成 - 所以它们最终 运行 按顺序而不是并行。
您也可以每隔几个周期调用一次 Thread.yield
以放弃您的时间片并让另一个线程 运行。
如果你愿意,我可以建议你可以处理的更合适的比赛条件
import java.util.concurrent.atomic.AtomicInteger;
/*
* author: Atom Karinca
*/
/*
* Run this program multiple times to see the output.
* How does the result vary? Why does that happen?
*
*/
class Racer extends Thread {
private static final int NUM_ITERS = 1000000;
public void run() {
for(int j = 0; j < NUM_ITERS; j++) {
RaceCondition.sum();
}
}
}
public class RaceCondition {
public static long sum = 0;
// What happens when you make this method "synchronized"?
// Do you still see the bug?
//synchronized
public static void sum() {
sum = sum + 1;
}
public static void main(String[] args) throws InterruptedException {
Racer leftAdder = new Racer();
Racer rightAdder = new Racer();
leftAdder.start();
rightAdder.start();
// wait for the threads to finish
leftAdder.join();
rightAdder.join();
System.out.println("Sum: " + sum);
}
}