我不明白Thread.sleep和'new'运算符是如何工作的

时间:2015-11-20 15:02:26

标签: java multithreading

有两件事我没有说清楚,一件涉及new操作员,另一件涉及方法Thread.sleep

// Create a second thread.
class NewThread implements Runnable {
  Thread t;

  NewThread() {
    // Create a new, second thread
    t = new Thread(this, "Demo Thread");
    System.out.println("Child thread: " + t);
    t.start(); // Start the thread
  }

  // This is the entry point for the second thread.
  public void run() {
    try {
      for(int i = 5; i > 0; i--) {
        System.out.println("Child Thread: " + i);
        Thread.sleep(500);
      }
    } catch (InterruptedException e) {
      System.out.println("Child interrupted.");
    }
    System.out.println("Exiting child thread.");
  }
}

class ThreadDemo {
  public static void main(String args[]) {
    new NewThread(); // create a new thread

    try {
      for(int i = 5; i > 0; i--) {
        System.out.println("Main Thread: " + i);
        Thread.sleep(1000);
      }
    } catch (InterruptedException e) {
      System.out.println("Main thread interrupted.");
    }
    System.out.println("Main thread exiting.");
  }

我知道new运算符用于分配对象  例如:Box refvar=new Box();调用Box类的构造函数  在这种情况下,呼叫是new NewThread();

但是我没有引用变量,我不明白Java如何在没有引用变量的情况下调用构造函数。通常我使用:Nameofclass reference-variable-name = new NameOfConstructor();.

我不明白的另一件事是:如果没有名称为Thread的对象,Java如何调用Thread.sleep()?在这种情况下应该是:t.sleep(1000)或不是?

提前致谢。

7 个答案:

答案 0 :(得分:3)

您可以在不指定引用的情况下调用构造函数。

在您的情况下,字段Thread t维护对线程的引用,因此不会过早收集垃圾。

Thread.sleep()当前线程休眠;即当前正在执行该位代码的线程。

答案 1 :(得分:2)

创建对象(new File())而不存储对象(File file = new File())是有效的。在这种情况下,您创建对象并调用构造函数,但不能对结果执行任何操作。在许多情况下,这不会做太多(但它可能会更改静态数据或抛出异常)。

在您的情况下,构造函数NewThread()实际上创建了一个线程并启动它。

关于Thread.sleep()的第二个问题实际上调用了类sleep中的静态函数Thread,它将等待给定的时间然后返回。所以这实际上将睡眠当前线程,而不是你调用它的另一个线程。请注意,即使在线程对象(someThread.sleep())上调用它仍然会休眠当前线程而不是someThread。在您的示例中,当前线程是主线程(由JVM创建并最终用于调用main函数)

答案 2 :(得分:1)

线程#sleep总是影响当前线程。不允许您定位其他线程以使其进入休眠状态。调用t.sleep()会导致调用静态方法,这会影响当前线程。在一个实例上调用静态方法是一个坏主意,它可能会误导读取代码的人认为代码正在使另一个线程进入休眠状态。

你的NewThread在构造函数中创建一个线程。一旦你启动一个线程,它将一直运行直到它终止,无论其他什么东西都引用它。每个线程都是GC根,可以防止它引用的任何内容的垃圾收集。保持对线程的引用将允许您中断它或以其他方式与其通信。

发布的代码看起来像是由一些人创建的,他们听说使用Runnable比扩展Thread更受欢迎,但谁错过了关于原因的观点。让Runnable为自己创建一个线程会破坏从执行任务(线程)的方式中分离Runnables(需要执行的任务)的目的。这不是设计任何实际代码的好方法,而不是造成混淆。

答案 3 :(得分:1)

Thread.sleep(...)

是可能的,因为sleep是一个静态方法

  

导致当前正在执行的线程进入休眠状态(暂时停止   执行)指定的毫秒数,受制于   系统定时器和调度程序的精度和准确度。

根据JavaDoc

答案 4 :(得分:1)

new NewThread();

在main中创建一个没有引用的新对象,因此在创建之后,您无法再在main中访问此对象。但无论如何都要创造这个对象。

Thread.sleep(1000);

其次,sleep是一个静态方法,因此你可以直接用classname调用这个方法,你不需要先为这个方法创建一个对象。

答案 5 :(得分:1)

1)new ClassName()将创建一个实例。即使您以后无法引用它,也可以在该实例上调用实例方法。

2)Thread类有一个名为sleep()的静态方法,静态方法不需要实例。可以使用className.methodName()

直接调用它们

答案 6 :(得分:0)

一般线程创建2路, 1.扩展Thread类 2.实现Runnable接口。

在这里,您选择了选项-2,例如可运行的接口。

在您的代码中,

您首先使用new Thread(...)关键字创建了new,其中包含了Runnable对象。

答案2:

Thread.sleep()方法:暂停当前线程的执行,在执行时,当前线程从线程生命周期的运行状态转移到等待/阻塞状态。 在completion of N-millisecond之后(这里是500,即0.5秒)。 那个帖子again wake up it and comes to Runnable state

如果还有任何疑问,请告诉我。