Java并发 - 这有效吗?

时间:2013-08-09 18:18:31

标签: java multithreading

System.out.println("Enter the number of what you would like to do");
System.out.println("1 = Manually enter Options");
System.out.println("2 = Use a text file to pick from pre-existing models");
System.out.println("3 = Exit ");


Scanner sc  = new Scanner(System.in);
try {
    runType = sc.nextInt();
    if(runType > 3) {
        throw new badValue(999, "Not the valid input");
    }
} catch (NullPointerException e) {
} catch (badValue e) {
    e.correctBadValue(runType);
} 

switch (runType) {
case 1:
    Thread a = new SelectCarOption();
    a.run();
case 2: 
    Thread a2 = new BuildCarModelOptions();
    a2.run();
case 3:
    System.exit(1); 

}

} }

基本上,我正在尝试运行一个程序,其中运行的线程由变量runType确定。如果runType是一个值,则某个线程将运行,如果是另一个,则另一个将运行。我的方法最有效吗?结果会出现任何错误吗?

5 个答案:

答案 0 :(得分:5)

长话短说不,不,这不是你想做的事情。

  1. thread1.run()没有启动新线程,它只调用当前线程上run()中的代码。你想要的是thread1.start()
  2. thread1.sleep(5000)不会让thread1睡眠,它会让线程进入睡眠状态。 Thread.sleep是一个影响当前线程的静态方法,并且您使用实例变量来调用它(而不是更传统的Thread.sleep(5000))这一事实并没有改变它。
  3. 启动thread2然后立即加入它是没有意义的。您也可以直接在主线程上调用其代码。 (这是你现在正在做的事情,因为你正在调用thread2.run()而不是thread2.start()。)
  4. 我不确定你的最终目标是什么,但这听起来像普通的旧多态。创建一个Runnable并根据输入将其分配给两个具体实现之一;然后只需在其上调用run()。类似的东西:

    Runnable selectStrategy = (runType == 2)
        ? new CarModelOptionsIO()
        : new SelectCarOption()
    
    selectStrategy.run()
    

    如果您需要此操作的结果,您可以使用Callable<T>(不要让包名混淆您;在该界面中没有固有的并发性)或甚至创建您自己的界面,为方法提供更有意义的名称(callrun非常无用)。

答案 1 :(得分:1)

  

程序员遇到了问题。他心想,#34;我知道,我会用线程来解决它!&#34;。现在有问题。两个他

<强> A)

你可以替换

    Thread thread1 = new SelectCarOption();
    thread1.start();
    thread1.join();

直接执行run所做的任何事情,因为启动线程的线程只是等待。

calling thread   | new thread

   start() ---->
                   run()
   join()        <---

做同样的事情
   run()

现在我们可以将您的代码简化为:

   if (runType == 2) {
       doCarModelOptionsIO();
   } else {
       doSelectCarOption()
   }

你有一个更有效的方式。

<强> B)

不要在线程上调用run()方法。直接调用的每个方法都在当前线程中执行。 Thread具有您调用的start()方法,然后在该新主题中调用run()

答案 2 :(得分:0)

您的代码中存在多个错误。并且让您知道,您编写的代码根本不会产生新的线程。几点需要注意:

Thread.sleep()是一种静态方法。以下代码具有误导性:

try {
  thread1.sleep(5000); //stops thread1 to run different thread 
} catch (InterruptedException e1) {
  e1.printStackTrace();
}

您已在主线程中启动了thread1,然后使用新创建的线程调用了sleep方法。但这不会帮助你。它使主线程睡眠不是thread1。要使thread1休眠,你需要在这个thread1类的run()中调用sleep方法 此外,sleep()是一个静态方法,不应该使用线程实例调用,这是误导性的。

停止线程并不一定意味着它将调用另一个线程。请记住,当涉及到螺纹加工时,保证很少。

还有一件事:

thread1.run(); // This is incorrect

使用thread1.start()

直接调用run()方法不会启动新线程。您需要调用start()方法来启动新线程。直接调用run方法将在同一个线程(从中调用它)执行run方法的内容

答案 3 :(得分:0)

总的来说,您的代码很混乱。如果您还没有,我建议reading the concurrency tutorials。如果您已阅读它们,请查看它们。也许你自己做一些,然后回到这个问题。

你说:

  

如果runType是一个值,则某个线程将运行,如果是另一个,则另一个将运行。

要做到这一点,你需要这样的东西......

    if (runType == 2) {
        Thread thread1 = new SelectCarOption();
        thread1.run();
        try {
            //join blocks until thread 1 terminates. We don't know that it
            //ever will give your code
            thread1.join(); //stops thread1 to run different thread 
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        Thread thread2 = new CarModelOptionsIO();
        thread2.run();
        try {
            //blocks again, until thread 2 is done running.
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    } else {

        try {
            thread1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //start some other thread here since runType is different?
    }

答案 4 :(得分:0)

你班上有很多错误。首先,您使用方法run()而不是start()。其次,你应该为你的睡眠启动两个线程()有意义。在线查看Oracle Java Se教程,了解Java多线程模型的基础知识,这将有很大帮助。