输出Java程序

时间:2017-12-11 09:09:43

标签: java multithreading

我正在尝试运行一个程序,我创建了3个线程。

1)Apple.Java

package Test;
import java.util.Random;

public class Apple implements Runnable{

    String name;
    int time;
    Random r = new Random();

    public Apple(String s){

        name = s;
        time = r.nextInt(999);
    }

    public void run(){

        try{
            System.out.printf("%s is sleeping for %d\n", name, time);
            //because we want each thread to sleep for random time.
            Thread.sleep(time);
            System.out.printf("%s is done\n" + name);

        }catch(Exception e){}
    }
}

2)ThreadTest.java

package Test;

public class Anand {

    public static void main(String[] args){

        Thread t1 = new Thread(new Apple("one"));
        Thread t2 = new Thread(new Apple("two"));
        Thread t3 = new Thread(new Apple("three"));
        t1.start();
        t2.start();
        t3.start();
    }
}

预期输出

one is sleeping for 934
three is sleeping for 383
two is sleeping for 228
two is done.
three is done.
one is done.

实际输出为:

当我跑步" ABC.java"作为Java应用程序,我得到以下输出:

one is sleeping for 934
three is sleeping for 383
two is sleeping for 228

在这里,我无法理解为什么以下声明没有被执行?或者为什么我没有在控制台上输出以下语句?

 System.out.printf("%s is done\n" + name);

4 个答案:

答案 0 :(得分:4)

此代码中的实际错误是:

java.util.MissingFormatArgumentException: Format specifier '%s'

ideone demo

因为:

System.out.printf("%s is done\n" + name);

应该是:

System.out.printf("%s is done\n", name);

请考虑这是一个说明性的示例,说明为什么空的catch块应该很少(如果有的话)。

}catch(Exception e){}  // Aaaargh! Nope nope nope.

至少打印堆栈跟踪:

}catch(Exception e){
  e.printStackTrace();
}

但是,请确保等待线程完成:

t1.join();
t2.join();
t3.join();

这是一个好习惯(类似于关闭流),而不是这个特定例子所必需的东西。

From the Javadoc of Thread

  

Java虚拟机继续执行线程,直到发生以下任一情况:

     
      
  • 已调用类Runtime的exit方法,安全管理器已允许退出操作。
  •   
  • 所有非守护程序线程的线程都已死亡,无论是通过调用run方法返回还是抛出一个超出run方法传播的异常。
  •   

OP的代码不会调用exit,因此这里不相关。所有线程都是非守护程序线程,因此执行将继续执行,直到它们全部完成(以某种方式)。换句话说,JVM将隐式插入join()以等待所有线程完成。因此,插入join,如其他答案中所建议的那样,实际上并没有做任何改变代码行为的事情。

答案 1 :(得分:4)

System.out.printf(“%s已完成\ n”+名称);

用System.out.printf替换上面的行(“%s已完成\ n”,名称);

现在它会起作用。

答案 2 :(得分:1)

这是因为main文件中的ThreadTest.java方法在执行其正文中的所有语句时停止执行。由于它是主线程,当main停止执行时,所有其他线程都会停止。

join()中使用main让它等待所有线程完成。

因此ThreadTest.java中的更正代码应为:

package theNewBostonTuts;

public class Anand {

    public static void main(String[] args){

        Thread t1 = new Thread(new Apple("one"));
        Thread t2 = new Thread(new Apple("two"));
        Thread t3 = new Thread(new Apple("three"));
        t1.start();
        t2.start();
        t3.start();

        t1.join();
        t2.join();
        t3.join();
    }
}

注意:System.out.printf文件中使用Apple.Java方法也存在问题。使用System.out.printf("%s is done\n", name);代替System.out.printf("%s is done\n" + name);

答案 3 :(得分:1)

主要在线程完成之前完成。 您将需要使用Thread.join等待它们中的每一个完成。

即。 ...

t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();

...

有关详细信息,请参阅https://www.journaldev.com/1024/java-thread-join-example