一、线程实现的三种方式
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口,需要实现的是call方法
二、代码的简单实现
package cn.xdf.threadpool;
public class RunnableDemo {
//1.继承 Thread方式的线程
public static class TestThreadDemo extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--继承 Thread方式--在运行!");
}
}
//2.1 实现runnable接口方式的线程
public static class TestRunnableDemo implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--实现runnable接口方式--在运行!");
}
}
public static void main(String[] args) {
//调用1. 继承 Thread方式
TestThreadDemo tt1 = new TestThreadDemo();
TestThreadDemo tt2 = new TestThreadDemo();
tt1.start();//Thread-0--继承 Thread方式--在运行!
tt2.start();//Thread-1--继承 Thread方式--在运行!
//调用2.1 实现runnable接口方式 的
TestRunnableDemo t1 = new TestRunnableDemo();
TestRunnableDemo t2 = new TestRunnableDemo();
new Thread(t1).start();//Thread-2--实现runnable接口方式--在运行!
new Thread(t2).start();//Thread-3--实现runnable接口方式--在运行!
//调用2.2 new Runnable对象方式
Runnable runnable = new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--new Runnable对象方式--在运行!");
}
};
new Thread(runnable).start();//Thread-4--new Runnable对象方式--在运行!
//这5个线程的调用顺序不一定
}
}
package cn.xdf.threadpool;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//3.2 new Callable方式的实现线程
Callable<String> callable = new Callable<String>(){//Callable方式的线程
@Override
public String call() throws Exception {
Random random = new Random();
return "返回值为:"+random.nextInt(200);//根据FutureTask 可以获取这个返回值!!!
}
};
FutureTask<String> futureTask = new FutureTask<>(callable);//根据FutureTask 获取返回值
new Thread(futureTask).start();//开启一个线程
String result = futureTask.get();//需要抛异常 //根据FutureTask 获取返回值
System.out.println("result:"+result);//result:返回值为:140
//3.1 实现Callable接口
TestCallableDemo cd1 = new TestCallableDemo();
FutureTask<String> ft = new FutureTask<>(cd1);//根据FutureTask 获取返回值
new Thread(ft).start();//开启一个线程
String rs = ft.get();//需要抛异常 //根据FutureTask 获取返回值
System.out.println("rs:"+rs);//rs:Thread-1--实现Callable接口方式的线程--在运行!
}
//3.1 实现Callable接口
public static class TestCallableDemo implements Callable{
@Override
public String call() throws Exception {
String result = Thread.currentThread().getName()+"--实现Callable接口方式的线程--在运行!";
return result;
}
}
}
三、总结:
1.Runnable接口的话,可以避免单继承的局限性,具有较强的健壮性。
2.Runnable可以实现资源的共享,同时处理同一资源。
3.Thread类的线程间都是独立运行的,资源不共享。
4.继承Thread类不再被其他类继承(java不存在多继承)
5.Callable是一个接口,Callable使用call( )方法,可以返回值;Runnable使用run( )方法,没有返回值。
6.call() 可以抛出受检查的异常,比如ClassNotFoundException, 而run()不能抛出受检查的异常