public class suspendCheck extends Thread{
int t ;
public static void main(String args[]) throws InterruptedException {
suspendCheck as = new suspendCheck();
Thread t2 = new Thread(as);
t2.start();
Thread t3 = new Thread(as);
t3.start(); }
public void run(){
if(t==0){
System.out.println("JAVA Develper");
t= ++t;
}
else{
System.out.println("JAVA Test");
}
}
}
多次运行此程序后,存在差异和差异:
通常:
JAVA Develper
JAVA Develper
偶尔:
JAVA Develper
JAVA Test
我为此感到震惊。我哪里出错了?
答案 0 :(得分:7)
是的,这是可以接受的。这里唯一可怕的事情是你试图使用线程而不知道它们的局限性。
您可以使用一个线程轻松完成此操作。你可以在这里采取安全的道路。
线程不保证有关优化和排序的任何内容。如果您确实希望int正确更改,请将其设为volatile
和/或使用AtomicInteger
。如果你想要更好的控制使用锁和/或synchronized
块。
在这种情况下,只需将t
声明为volatile并同步访问t
或AtomicInteger并使用该类的方法访问t
。
为了将来参考,在没有阅读所有相关警告的情况下尝试这些事情可能导致死亡,窒息,发冷,发烧,溺水,感染,恶心和the inability to control highly expensive machinery。
答案 1 :(得分:1)
我只想补充一下你应该在竞争条件下阅读的六人回答:
并解释你在代码中所做的是使多个线程尝试获取一个整数并以一种方式更改它,而其中一个可以在另一个线程获取它时改变它,从而覆盖给定的值由第一个线程。这就是你得到这种行为的原因
Java中的竞争条件是一种并发错误或问题 在您的程序中引入,因为并行执行您的程序 由多个线程同时进行,因为Java是一个多线程的 编程语言因此Java中竞争条件的风险更高 这需要清楚地了解导致种族状况的因素 如何避免这种情况。
答案 2 :(得分:0)
你不能保证线程的执行顺序。当你在一个线程上调用start()
方法时,它现在由线程调度程序决定应该执行的顺序
t1.start();
t2.start();
这并不意味着t1
肯定会在t2
之前运行。在您的示例中,您没有同步方法,线程可能同时运行,或者当一个线程到达第4行时,另一个可能已经完成执行。
public void run(){
if(t==0){
System.out.println("JAVA Develper");
t= ++t; //Line 4
}
else{
System.out.println("JAVA Test");
}
}
同步方法将为线程提供对象的锁定。没有与runnable具有相同对象的其他线程将能够同时访问同步块或方法。
synchronized public void run()
答案 3 :(得分:0)
如果需要并行发生,则应该使用线程,而不是串行。除非你明确地同步,哪种打破了线程的想法,否则事情将以未定义的顺序发生。
了解线程并使其绝对正确对于任何语言都是至关重要的,也是最困难的事情。
我建议在joshua bloch的实践中阅读java并发,看看使用线程时有多少pittfalls,更重要的是,共享状态。