关于创建线程的四种方式
今天学习了线程,了到了线程的四种创建方式 分别是 1.继承Thread 2.实现Runnable接口 3.实现Callable接口 4.使用线程池 下面我们来分别说一下啊这些方式的区别,和实现
1.Thread
继承Thread 重写run方法
package com.cyc.test;
//创建一个类继承Thread重写run方法
public class ThreadDemo extends Thread{
//重写run方法
@Override
public void run() {
show();
}
public void show(){
for (int i=1;i<=100;i++){
System.out.println(i);
}
}
public static void main(String[] args){
//创建线程
ThreadDemo threadDemo = new ThreadDemo();
//启动线程
threadDemo.start();
}
}
2.实现Runnable接口
实现run方法 在一些特殊时候,某些类已经继承了其他抽象方法时,想要启用线程只能使用接口
package com.cyc.test;
public class RunnableDemo implements Runnable{
//实现run方法
@Override
public void run() {
show();
}
public void show(){
for (int i=1;i<=100;i++){
System.out.println(i);
}
}
public static void main(String[] args){
//创建线程
RunnableDemo runnableDemo = new RunnableDemo();
Thread t1=new Thread(runnableDemo);
//启动线程
t1.start();
}
}
3.实现Callable接口
可以带着返回值 实现call方法
package com.cyc.test;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableDemo implements Callable<Integer> {
//实现call方法
@Override
public Integer call() throws Exception {
int num=0;
for (int i=1;i<=100;i++){
num+=i;
}
return num;
}
public static void main(String[] args){
//创建线程
CallableDemo callableDemo = new CallableDemo();
FutureTask<Integer>task=new FutureTask<>(callableDemo);
//线程启动
Thread t1=new Thread(task);
t1.start();
try {
//获得返回值
int i=task.get();
System.out.println(i);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
FutureTask实现了FutureRunnable接口,Future接口有5个方法:
1、boolean cancel(boolean mayInterruptIfRunning) 尝试取消当前任务的执行。如果任务已经取消、已经完成或者其他原因不能取消,尝试将失败。如果任 务还没有启动就调用了cancel(true),任务将永远不会被执行。如果任务已经启动,参数 mayInterruptIfRunning将决定任务是否应该中断执行该任务的线程,以尝试中断该任务。 如果任务不能被取消,通常是因为它已经正常完成,此时返回false,否则返回true
2、boolean isCancelled() 如果任务在正常结束之前被被取消返回true
3、boolean isDone() 正常结束、异常或者被取消导致任务完成,将返回true
4、V get() 等待任务结束,然后获取结果,如果任务在等待过程中被终端将抛出InterruptedException,如果任务 被取消将抛出CancellationException,如果任务中执行过程中发生异常将抛出ExecutionException。
5、V get(long timeout, TimeUnit unit) 任务最多在给定时间内完成并返回结果,如果没有在给定时间内完成任务将抛出TimeoutException。
具体方法请参考juejin.cn/post/684490…
4.线程池
package com.xc.pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPool {
public static void main(String[] args) {
//执行服务对象,ExecutorService负责从线程池中找出线程来执行任务
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.execute(new Task1());
executorService.execute(new Task2());
executorService.execute(new Task3());
}
static class Task1 implements Runnable{
@Override
public void run() {
for (int i = 0; i <100 ; i++) {
System.out.println(Thread.currentThread().getName()+ " task1:"+i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Task2 implements Runnable{
@Override
public void run() {
for (int i = 100; i >=0 ; i--) {
System.out.println(Thread.currentThread().getName()+ " task2:"+i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Task3 implements Runnable{
@Override
public void run() {
for (int i = 0; i <100 ; i++) {
System.out.println(Thread.currentThread().getName()+ " I Love you....");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}