Java并发编程(Java Concurrency)(7)- 创建并启动 Java 线程

原文链接:http://tutorials.jenkov.com/java-concurrency/creating-and-starting-threads.html

摘要:这是翻译自一个大概30个小节的关于Java并发编程的入门级教程,原作者Jakob Jenkov,译者Zhenning Lang,转载请注明出处,thanks and have a good time here~~~(希望自己不要留坑)

Java 线程如 Java 中其他对象一样也是一个对象。线程是 java.lang.Thread 的实例,或者是其子类的实例,Java 线程用来执行代码。

1 Java 线程视频教程

下面的链接是一个 Java 线程的视频教程
https://www.youtube.com/embed/9y7l6QHpoQI

2 创建并启动线程

Java 中像这样创建一个线程:

Thread thread = new Thread();

为了使这个线程启动,需要调用其 start() 方法,

thread.start();

上面的例子没有指定这个线程需要执行的代码,所以这个线程将在启动后立刻结束。

有两种方法来指定线程需要执行的代码。第一种是创建 Thread 的子类并覆盖其 run() 方法,第二种方法是向 Thread 的构造函数传递一个实现了 Runnable(java.lang.Runnable) 接口的对象,下面将分别予以介绍。

2.1 创建Thread 的子类

第一种指定线程执行代码的方法是创建一个 Thread 类的子类并覆盖其 run() 方法,run() 的内部的代码就是调用 start() 后所执行的代码,如下例所示:

public class MyThread extends Thread {
    public void run(){
        System.out.println("MyThread running");
    }
}

创建并启动上面线程的代码如下:

MyThread myThread = new MyThread();
myTread.start();

start() 函数被调用后,当线程开始将立刻返回,而不会等到 run() 中的代码被执行完毕。run() 方法将在新线程中被执行,就好像在一个独立的 CPU 中。上例中 run() 方法将打印“MyThread running”。

也可以使用匿名内部类来实现上面的内容:

Thread thread = new Thread(){
    public void run(){
        System.out.println("Thread Running");
    }
}
thread.start();

2.2 实现 Runnable 接口

第二种指定多线程执行代码的方法是创建一个实现 java.lang.Runnable 接口的类。Runnable 对象可以被线程执行。下面是一个简单示例:

public class MyRunnable implements Runnable {
    public void run(){
       System.out.println("MyRunnable running");
    }
}

为了让 run() 方法中的代码被线程执行,需要将 MyRunnable 类的实例传给 Thread 的构造函数,如下所示:

Thread thread = new Thread(new MyRunnable());
thread.start();

当 thread 启动时,它会调用 MyRunnable 类的实例的 run() 方法,而不是其自己的 run() 反复。上例会打印“MyRunnable running”。

也可以以匿名内部类的方式实现 Runnable 接口,如下所示:

Runnable myRunnable = new Runnable(){
    public void run(){
        System.out.println("Runnable running");
    }
}
Thread thread = new Thread(myRunnable);
thread.start();

3 常见错误:错把 run() 方法当做 start() 方法

当创建和启动新线程时一个常见的错误是调用 run() 方法来启动线程,而没有调用 start() 方法,如下:

Thread newThread = new Thread(MyRunnable());
newThread.run();  //should be start();

虽然一开始一切看起来都很正常,运行结果也符合你的预期,但代码并没有在新线程中执行,而是在创建新线程的线程中被执行了。换言之就是没有创建新的线程。

4 线程名

当你创建一个 Java 线程时你可以给其取一个名字,用于帮助你区分不同的线程。举例来说,如果多个线程都调用 System.out,那么很难判断究竟是哪个线程进行了输出。下面是给线程指定名称的例子:

Thread thread = new Thread("New Thread") {
    public void run(){
        System.out.println("run by: " + getName());
    }
};
thread.start();
System.out.println(thread.getName());

上面传给 Thread 构造函数的字符串“New Thread”就是线程的名字。这个名字可以通过 Thread 类的 getName() 方法来获得。实现 Runnable 接口的方式下给线程赋名字的示例如下:

MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable, "New Thread");
thread.start();
System.out.println(thread.getName());

这里需要注意的是,由于 MyRunnable 类并不是 Thread 的子类,所以 MyRunnable 类内的 run() 方法并不能调用 getName() 方法(当然,可以通过 Thread.currentThread().getName() 实现这个功能)。

5 Thread.currentThread()

Thread.currentThread() 方法返回执行 Thread.currentThread() 函数的线程的实例引用。通过这种方法可以在代码中获得当前线程的 Thread 对象,如下例所示:

Thread thread = Thread.currentThread();

一旦获得了 Thread 对象的引用,就可以调用其中的方法。下例展示了如何获得当前线程的名称:

String threadName = Thread.currentThread().getName();

6 实例

下面是一个实例。首先打印出 main() 方法所在线程的线程名称(该线程名称由 JVM 分配);然后启动 10 个线程,并且给每个线程赋一个名字,其格式是 “” + i;每个线程的工作是输出自己的线程名,然后停止:

public class ThreadExample {
    public static void main(String[] args){
        System.out.println(Thread.currentThread().getName());
            for(int i=0; i<10; i++){
                new Thread("" + i){
                    public void run(){
                        System.out.println("Thread: " + getName() + " running");
                    }
                }.start();
            }
        }
    }

注意到虽然每个线程都是按照 1,2,3, … 的顺序被创建和启动的,但其执行顺序却可能不是这个顺序。例如线程 1 可能不是第一个执行输出的线程。这是因为本质上这些线程是并行而非顺序执行的。JVM 和/或者操作系统将决定线程的执行顺序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值