在Java中提供了3种创建线程的方法:
1、通过实现Runnable接口
2、通过继承Thread类本身
3、通过Callable或者Future创建线程
实现Runnable接口创建线程类
1、定义Runnable接口的实现类,重写run()方法
2、创建Runnable实现类的实例,并以此作为Thread的target来创建对象,该对象才是真正的线程对象。
package duoxiancheng;
public class NewThread implements Runnable {
private int i = 0;
@Override
public void run() {
for(;i<100;i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
public static void main(String[] args) {
for(int i = 0;i<100;i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
if(i == 20) {
NewThread test = new NewThread();
new Thread(test,"新线程1").start();
new Thread(test,"新线程2").start();
}
}
}
}
继承Thread类创建线程类
1.重写run方法。该run()方法的方法体就代表了线程需要完成的任务。
2.创建Thread子类的实例。
3.调用线程对象的start()方法来启动该线程。
package duoxiancheng;
public class ThreadTest extends Thread {
private int i;
public void run() {
for(;i<100;i++) {
System.err.println(getName()+" "+i);
}
}
public static void main(String[] args) {
for(int i =0;i<100;i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
if(i == 20) {
new ThreadTest().start();
new ThreadTest().start();
}
}
}
}
使用Callable和Future创建线程
1.创建Callable接口的实现类,并实现Call()方法,该方法将作为线程执行体,且该方法有返回值,再创建Callable实现类的实例。从Java8开始,可以直接使用Lambda表达式创建Callable对象。
2.使用FutureTask来包装Callable对象,该FutureTask对象封装了该Callable对象的call方法的返回值。
3.使用FutureTask对象作为Thread对象的target创建并启动新线程。
4.调用FutureTask对象的get()方法来获取子线程执行结束后的返回值。
package duoxiancheng;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class NewThread2 {
public static void main(String[] args) {
Callable<String> callable = new CallableThread();
FutureTask<String> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
Do();
try {
System.out.println(futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
private static void Do() {
System.out.println("静态方法Do()");
}
}
package duoxiancheng;
import java.util.concurrent.Callable;
public class CallableThread implements Callable<String>{
@Override
public String call() throws Exception {
return "hello world";
}
private void Do() {
System.out.println("我是线程中的方法");
}
}
Callable接口是一个带泛型的接口,泛型的类型就是线程返回值的类型。实现Callable接口中的call()方法,方法的返回类型与泛型的类型相同。Callable不能直接获取返回值,需要用FutureTask<V>在外部封装一下再获取返回值。