文章目录
1、多线程主要的实现方式:
一种是继承Thread类
一种实现Runnable接口
2、继承Thread类和实现Runnable接口的区别:
-
由于Java是单继承方式,如果线程类已经继承了其它类,就不能使用继承Thread类的方式,但是可以转而使用实现Runnable接口的方式
-
Thread类的run方法不能共享,比如说线程A不能把线程B的run方法当成是自己的执行单元,而使用Runnable则可以很容易实现,因为同一个Runnable可以构造多个实例,通俗的说可以理解Runnable相当于是Thread的task
-
从职责上来讲,Thread类主要负责线程本身相关职责与控制,而Runnable主要负责线程逻辑的执行单元
3、线程实现的所有方式
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口,并通过FutureTask进行包装
- 使用匿名内部类
- 使用Lambda表达式
- 使用线程池
- 使用定时器
3.1、继承Thread类
public class Thread1 extends Thread {
@Override
public void run() {
System.out.println("继承Thread方式");
}
public static void main(String[] args) {
Thread1 thread = new Thread1();
thread.start();
}
}
3.2、实现Runnable接口
public class Thread2 implements Runnable {
@Override
public void run() {
System.out.println("实现Runnable接口方式");
}
public static void main(String[] args) {
Runnable runnable = new Thread2();
Thread thread2 = new Thread(runnable);
thread2.start();
}
}
3.3、实现Callable接口,并通过FutureTask包装
public class Thread3 implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(5000);
return "实现Callable方式,并通过FutureTask包装,有返回值";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
Thread3 thread3 = new Thread3();
FutureTask futureTask = new FutureTask(thread3);
Thread thread = new Thread(futureTask);
thread.start();
System.out.println("线程已经启动");
// 同步方式获取返回结果
String result = (String) futureTask.get();
System.out.println(result);
}
}
3.4、匿名内部类
匿名内部类也有多种变体,上述三种方式都可以使用匿名内部类来隐式实例化。
public class Demo{
public static void main(String[] args) throws Exception {
//方式一:Thread匿名内部类
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
}
}.start();
//方式二:Runnable匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
}).start();
...
}
}
匿名内部类的优点在于使用方便,不用额外定义类,缺点就是代码可读性差。
3.5、Lambda表达式
public class Demo{
public static void main(String[] args) throws Exception {
new Thread(() -> System.out.println("running") ).start() ;
...
}
}
Runnable被@FunctionalInterface注解所修饰,并且接口中仅有一个方法
3.6、线程池
public class DemoThreadTask implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("running");
}
public static void main(String[] args) {
DemoThreadTask task = new DemoThreadTask();
ExecutorService ex = Executors.newCachedThreadPool();
ex.execute(task);
}
}
3.7、定时器
public class DemoTimmerTask {
public static void main(String[] args) throws Exception {
Timer timer = new Timer();
timer.scheduleAtFixedRate((new TimerTask() {
@Override
public void run() {
System.out.println("任务执行");
}
}), 2000, 1000);
}
}
TimerTask的实现了Runnable接口,Timer内部有个TimerThread继承自Thread。