-1
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

我对此感到恐惧。我哪里做错了?

4

4 回答 4

7

是的,这是可以接受的。这里唯一可怕的是你试图在不知道它们的限制的情况下使用线程。

您可以使用一个线程轻松完成此操作。你可以在这里走安全的道路。

线程不保证任何关于优化和排序的事情。如果您真的希望您的 int 正确更改,请制作volatile和/或使用AtomicInteger. 如果您想要更好的控制,请使用锁和/或synchronized块。

在这种情况下,只需声明t为 volatile 并围绕对 AtomicInteger 的访问进行同步,t并使用该类的方法来访问t.

以供将来参考,在不阅读所有相关警告的情况下尝试此类操作可能会导致死亡、窒息、寒战、发烧、嗜睡、感​​染、恶心以及无法控制昂贵的机器

于 2013-09-01T08:21:08.843 回答
1

我只是想添加到你应该在比赛条件下阅读的十六进制答案:

并解释您在代码中所做的是让多个线程尝试获取一个整数并以其中一个线程可能会更改它的方式更改它,而另一个线程正在使用它,从而覆盖第一个给定的值线。这就是为什么你会得到这种行为

Java 中的竞态条件是一种并发错误或问题,它会在您的程序中引入,因为您的程序同时由多个线程并行执行,由于 Java 是一种多线程编程语言,因此在 Java 中竞态条件的风险更高需要清楚地了解导致竞争条件的原因以及如何避免这种情况。

于 2013-09-01T08:28:39.627 回答
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");
            }

        }

同步方法将为线程提供对象锁定。没有其他线程具有与可运行对象相同的对象,将能够同时访问同步块或方法。

 synchronized public void run()
于 2013-09-01T08:49:12.893 回答
0

如果事情需要并行而不是串行发生,您应该使用线程。除非您明确同步,否则会破坏线程的概念,否则事情将以未定义的顺序发生。

理解线程并使其完全正确对于几乎任何语言来说都是至关重要的,也是最困难的事情。

我建议阅读 joshua bloch 的 java concurrency in practice,看看在使用线程时有多少陷阱,更重要的是,共享状态。

于 2013-09-01T08:56:07.617 回答