java 8 jdk源码 而言
1. 创建Thread的子类
There are two ways to create a new thread of execution.
One is to declare a class to be a subclass of Thread.
This subclass should override the run method of class Thread.
An instance of the subclass can then be allocated and started.
For example, a thread that computes primes larger than a stated value could be written as follows:
大意:创建一个新的执行线程有两种方法。
一种是声明一个Thread的子类,并且重写Thread类的run方法。
然后这个子类创建的实例可以被启动和分配资源。
下面是一个计算大于规定值素数(prime)的线程:
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
// 计算大于minPrime的素数
. . .
}
}
The following code would then create a thread and start it running:
//创建一个线程并调用它运行(计算大于143的素数)
public static void main(String[] args){
PrimeThread p = new PrimeThread(143);
p.start();
}
2. 创建Runnable接口的实现类
The other way to create a thread is to declare a class that implements the Runnable interface.
That class then implements the run method.
An instance of the class can then be allocated, passed as an argument when creating Thread, and started.
The same example in this other style looks like the following:
大意:另一种方法是创建一个Runnable接口的实现类作为线程。
同样要实现run方法
接着可以给这个类分配个实例,在创建线程时作为参数传递,并启动
以下是例子(找素数):
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
The following code would then create a thread and start it running:
//创建一个线程并调用它运行(计算大于143的素数)
public static void main(String[] args){
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
}
Every thread has a name for identification purposes.
More than one thread may have the same name.
If a name is not specified when a thread is created, a new name is generated for it.
Unless otherwise noted,
passing a null argument to a constructor or method in this class will cause a NullPointerException to be thrown.
大意:每一个线程都有个名称用来识别。
多个线程可能有相同的名称。
如果在线程创建时未指定名称,则会为其生成一个新名称。
除非另有说明,否则把null参数传递给线程的构造器或方法
需要抛出一个NullPointerException的异常
以上两种方法都是调用Thread.start()方法, 再start()方法调用 run()方法
另外
3. 实现Callable接口
A task that returns a result and may throws an exception.
Implementors define a single method with no arguments called call.
The Callable interface is similar to Runnable,in that both are designed for classes whose instances are potentially executed by anoter thread.
A Runnable,however does not return a result and cannot throw a checked exception.
The Executors class contains utility methods to convert form other common forms to Callable classes.
大意:这是一个用来返回结果并可能抛出异常的任务。
实现类需要定义一个无参的 call() 构造方法.
Callable 接口类似于Runnable 接口,都是设计成先创建一个实现类,然后再创建一个实例,再给线程执行。
一个Runnable接口不会返回结果,也不能抛出检查型异常。
Excecutors类中包含将其他形式的类转为Callable的实用方法。`
以下是个例子:
/**
* 1.MyThread实现Callable接口,返回一个值
* 2.将MyThread作为FutureTask的参数
* 3.将FutureTask 的实例task作为Thread类的参数,相当于创建一个线程任务
* 4.通过FutureTask的get方法获取线程的执行结果
*/
public class TestFuture{
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<Integer> task= new FutureTask<>(new MyThread());
new Thread(task).start();
Integer result = task.get();
System.out.println(result);
}
}
class MyThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
return new Random().nextInt(10);//[0,10)
}
}
4.借用线程池创建
/**
* 1.实现Runnable接口,重写run方法
* 2.用Executors来创建一个100单位容量的线程池
* 3.最后交给ExcetorService对象的execute方法传入线程对象
*/
public class TestPool{
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(100);
for (int i = 0; i < 100; i++) {
executorService.execute(new MyThread());
}
}
}
class MyThread implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}