这个threadExample是如何工作的?

时间:2012-03-08 02:17:47

标签: java multithreading

我想在一个类下编写多个线程,并找到了一种方法。

public class ThreadExample {

    public static void main(String[] arg) 
    {

        Thread one = new Thread() {
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch(InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("One");
            }
        };

        Thread two = new Thread() {
            public void run() {
                System.out.println("Two");
            }
        };

        one.start();
        two.start();    
    }
}

我没有到达这里,我既没有扩展Thread类,也没有实现Runnable接口。我怎么理解这个? 如果答案是“我只是创建Thread类的对象并使用它,那么为什么不总是这样做而不是做上面提到的事情呢?

3 个答案:

答案 0 :(得分:2)

从技术上讲,您正在做的正在扩展Thread。您正在使用称为匿名内部类的东西进行扩展 - 要了解有关内容的更多信息,请启动here并阅读此页面以及接下来的两页。

这意味着您正在创建没有名称的临时内联子类,并且其定义仅在方法完成后才存在。为什么这样做而不是创建Thread的命名子类或Runnable的实现?当run()的主体与上面的例子一样简单时,它是有意义的 - 键入的内容更少,.java文件更少,无法跟踪。像这样的一次性简单任务是Thread的匿名内部类扩展的良好候选者。对于主程序逻辑,您可能希望在单独的文件中执行完整的命名类实现。

此外,一旦您获得了Thread的良好体验,我建议您查看java.util.concurrent包。

答案 1 :(得分:2)

啊,但你 匿名延长Thread班级。

使用new Class() {}语法时,您创建的anonymous class是指定类的子类(即有效extends)。

在这种情况下,您已覆盖Thread.run()方法。

这种方法虽然有效,但它不被认为是“好的设计”,因为你正在扩展Thread,但你并没有创建一种新的Thread。最好将Runnable传递给构造函数:

new Thread( new Runnable() {
    public void run() {
        // do something
    }
}).start();

答案 2 :(得分:1)

波西米亚回答了你的第一个问题所以我会回答你的第二个问题:“我只是创建Thread类的对象并使用它,那为什么不总是这样做而不是做上面提到的事情?”

如果你总是像你在问题中那样做,那么你就无法将执行任务的逻辑与任务的运行方式分开。通过实现runnable,您可以将执行任务的逻辑与管理任务运行方式的代码分开。

如果您使用runnables,您可以在新线程中运行您的任务,在调用线程中运行您的任务,在延迟一段时间后运行您的任务或以其他方式运行它而无需修改runnable中的代码。

使用线程时,通常需要使用ExecutorService而不是直接使用线程类。 Executor服务提供了限制线程数量,处理失败执行,确定runnable何时完成,从其他线程中运行的任务获取返回值等设施。