Chapter 1.2 线程对象

2019-10-14  本文已影响0人  原创迷恋者

本文翻译自Oracle Java Document Concurrency篇
原文链接如下:https://docs.oracle.com/javase/tutorial/essential/concurrency/threads.html

线程对象

在JAVA中,每个线程都和Thread类有关。为了创建并发的程序,使用Thread对象有两个基本的策略。

定义和开启一个线程

一个创建线程的应用必须要提供在这个线程中运行的代码。有两种方式来创建一个线程:

  1. 提供一个Runnable的对象。Runnable接口定义了一个方法,run,为了包含在该线程中运行的代码。Runnable对象被传递给Thread构造器,如下的代码所示:
public class HelloRunnable implements Runnable {
    public void run() {
        System.out.println("Hello from a thread!");
    }

    public static void main(String args[]) {
        (new Thread(new HelloRunnable())).start();
    }
}
  1. 作为Thread的子类。Thread类本身也实现了Runnable接口,尽管它的run方法什么也没做。一个应用可以成为Thread的子类,然后提供自己的run方法实现,如下代码所示:
public class HelloThread extends Thread {
    public void run() {
        System.out.println("Hello from a thread!");
    }

    public static void main(String args[]) {
        (new HelloThread()).start();
    }
}

注意到,两种方式都使用Thread.start方法来启动新的线程。

那么你应该倾向于使用哪种方法呢?第一种方法,构造了一个Runnable对象,是一个更为通用的方法,因为Runnable对象可以承载除了Thread类的其他子类。第二种方法在简单的应用中比较容易实现,但它的局限性是任务类必须是Thread的子类。本教程会集中讲解第一种方法,因为它不仅拥有更好的扩展性,而且也更容易应用高层次的线程管理API。

Thread类中定义了一系列对线程管理有用的方法,包括一些静态的方法,可以提供、影响调用该方法的线程的状态。其他方法是由其他线程发起的,来管理线程和线程对象。我们会在后续的章节看到这些方法。

使用Sleep方法停止执行

Thread.sleep方法会让当前的线程停止运行一段时间。这是一种把处理器时间提供给其他线程的有效方法。sleep方法也能用来作为节奏器,如下的代码所示。

还有两种重载的sleep方法,一个以毫秒为单位具体指出了休眠的时间,另一个以纳秒为单位指定了休眠时间。不过,这些休眠时间并不保证精确,因为被OS之下的机制所限制。此外,休眠过程也可能被中断打扰。总之, 你不能指望调用sleep方法就能准确延迟线程你指定的时间。

下面的SleepMessage类使用sleep方法,以四秒的间隙,来打印信息。

public class SleepMessages {
    public static void main(String args[]) throws InterruptedException {
        String importantInfo[] = {
            "Mares eat oats",
            "Does eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };

        for (int i = 0; i < importantInfo.length; i++) {
            //Pause for 4 seconds
            Thread.sleep(4000);
            //Print a message
            System.out.println(importantInfo[i]);
        }
    }
}

注意到main方法抛出了InterruptedException。这个异常会在当前进程休眠被其他进程打扰时抛出。不过既然当前的方法里只有一个线程,那也就不会导致这个异常。

上一篇下一篇

猜你喜欢

热点阅读