我只需要用java线程做一个竞争条件的例子,我写了这个代码,但我不确定它是否有竞争条件。
有人可以告诉我下面的代码是否有竞争条件,还有我如何改进它或简化它?
(抱歉英语不好)
public class RaceCondition extends Thread{
static int count=0; //the variable where the race condition need to happen
static int contador1 = 0; //variables to count
static int contador2 = 0;
static Thread t1 = new Thread(new Runnable() {
public void run(){
while(contador1!=20){
count ++;
System.out.print(count + " ");
contador1++;
}
}
});
static Thread t2 = new Thread(new Runnable() {
public void run(){
while(contador2!=20){
int k = 5;
count += 5*k;
System.out.print(count + " ");
contador2 ++;
}
}
});
public static void main(String[] args) {
t1.start();
System.out.println(" ");
t2.start();
}
}
答案 0 :(得分:6)
你确实有竞争条件。 ++
或+=
操作都不是作为Java中的原子操作实现的,当两个线程都尝试读取和更新计数字段时,这两个线程可能会相互干扰。
此外,无法保证跨线程可以看到共享变量的更新,因此一个线程甚至可能看不到其他线程的更新值。
您可以通过将计数静态变量设为AtomicInteger来解决这两个问题。使用getAndIncrement代替++
,getAndAdd代替+=
。
++
的工作原理如下:Why ++ is not implemented as an atomic operation in Java。
答案 1 :(得分:0)
您没有任何竞争条件。线程仅分别访问变量contador1
和contador2
。两个线程都没有修改或读取的变量。
t2
甚至拥有自己使用的本地k
,而不是您标记的k
。
count
在哪里宣布?
答案 2 :(得分:0)
为了具有竞争条件,您需要具有读/写共享内存部分的线程(例如全局/静态变量)。在这里,你的线程没有交互,因此没有竞争条件。此外,您在线程2代码中重新声明k
,因此永远不会使用您的全局k
。
请改为尝试:
public class RaceCondition extends Thread{
static int k = 0; //the variable where the race condition need to happen
public void run(){
while( k != 20 ){
k++;
try{
Thread.sleep( 1 );
}catch( InterruptedException e ){
}
System.out.print( k + " " );
}
}
public static void main( String[] args ){
RaceCondition t1 = new RaceCondition();
RaceCondition t2 = new RaceCondition();
t1.start();
t2.start();
}
}
答案 3 :(得分:0)
"当两个或多个线程可以访问共享数据并且他们尝试同时更改它时,会出现争用情况。因为线程调度算法可以在任何时间在线程之间交换,所以您不知道线程将尝试访问共享数据的顺序。因此,数据变化的结果取决于线程调度算法,即两个线程都是"赛车"访问/更改数据。" SOURCE = What is a race condition?
注意这部分"数据变化的结果取决于线程调度算法"以及如何在代码中操作变量计数。
答案 4 :(得分:0)
没有。当两个或多个线程访问导致结果出现问题的同一变量时,就会出现竞争条件。例如,
static int a = 2;
static int b = 0;
static Thread t1 = new Thread(new Runnable() {
public void run(){
if(a == 2) {
b = 5 * a;
System.out.println(a);
}
}
});
static Thread t2 = new Thread(new Runnable() {
public void run(){
a = 5;
}
});
这里,考虑在Thread1执行if(a == 2)
之后,Thread2更改了a = 5
的值。因此,我们不会获得预期值10,而是获得25
。
答案 5 :(得分:-1)
这是代码:
package RaceCondition;
public class RaceCondition extends Thread {
static int count = 0;
static int contador1 = 0;
static int contador2 = 0;
static Thread t1 = new Thread(new Runnable() {
public void run() {
while (contador1 != 20) {
count++;
System.out.print(count + " ");
contador1++;
}
System.out.println("fine t1");
}
});
static Thread t2 = new Thread(new Runnable() {
public void run() {
while (contador2 != 20) {
int k = 5;
count += 5;
System.out.print(count + " ");
contador2++;
}
System.out.println("fine t2");
}
});
public static void main(String[] args) {
t1.start();
System.out.println(" ");
t2.start();
}
}