Thread类
Thread类实现了Runnable接口,所以Thread类对象也是Runnable对象,同时Thread类也是线程类Runnable r=new Thread();
构造器:
Thread() //一般用于在Thread类中覆盖定义run方法,可以使用匿名内部类的方式进行定义
Thread(Runnable) //使用最多的情形,run方法是通过Runnable对象提供的
Thread(String) //创建线程对象的同时设置线程名称
Thread(Runnable,String)
//常见的简化写法
Thread t=new Thread(()->{
System.out.println(Thread.currentThread());
});
t.start();
Runnable接口
Runnable接口中只定义了一个方法public void run(),Runnable对象一般称为可运行对象,一个线程对象运行的就是Runnable对象中的run方法.
public class MyRunnable implements Runnable{
public void run() throws Exception{ //语法报错,因为不允许抛出异常,如果run方法中有可能会有受检型异常,则需要使用try/catch结构进行处理。
//没有返回值,如果需要记录处理结果,必须自己编程实现
}
}
//简化写法
new Thread(()->{
for(int i=0;i<100;i++){
System.out.println("左手。。。。");
try{
Thread.sleep(100); //这里有一个受检型异常,因为run不允许抛出异常,所以必须使用try/catch进行处理
} catch(InterruptedException e){
e.printStackTrace();
}
}
}).start();
Callable接口
继承Thread类或者实现Runnable接口都有一个缺陷:在执行完成后无法获取执行结果。如果需要获取执行结果,就必须通过共享变量或者使用线程之间通信Pipedxxx管道流的方式来实现,这样使用非常的麻烦。引入Callable接口的目的就是获取执行结果。
Callable接口中有一个方法call,call方法要求有返回值,这个返回值可以通过泛型进行约束,并且允许抛出异常。
public class MyCallable implements Callable<Number> {
public Number call() throws Exception{
return 100; --- int
return 100.0; --- double
} //call方法的返回值类型要和Callable接口后面<>中的类型一致。数值型的包装类的父类型就是Number }
//简化写法
new Thread(new FutureTask<>(()->{
for(int i=0;i<10;i++){
Sytem.out.println("右手。。。。");
Thread.sleep(30);//允许抛出异常
}
return null; //必须有返回值
})).start();
Future接口
Future接口对象用于表示一个任务的生命周期,提供了一组方法用于判断是否已经完成或者取消,以及获取任务的执行结果或取消任务。必要时可以通过get()方法获取线程的执行结果,该方法可以阻塞当前线程直到任务结束为止或者超时。
public class Test1 {
public static void main(String[] args) throws Exception {
Future f = new FutureTask(() -> {
for (int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread() + "...start...");
Thread.sleep(10);
System.out.println(Thread.currentThread() + "...end...");
}
return 100;
});
if(f instanceof Runnable) {
new Thread((Runnable)f).start();
int count=0;
while(true) {
Thread.sleep(20);
System.out.println("任务是否被取消:"+f.isCancelled()+"--- "+count);
System.out.println("任务是否已经完成:"+f.isDone());
count++;
if(count>10)
f.cancel(true); //取消任务的执行
if(count>20)
break;
}
}//如果任务是取消的方式完成的,这里获取返回值出现异常java.util.concurrent.CancellationException。可以通过这个异常判定取消的方式完成的任 务,不是正常结束,如果正常结束会有返回值,哪怕是null
System.out.println("获取到的返回止:"+f.get());
}
}
FutureTask类
FutureTask实现了两个接口Runnable和Future,所以它既可以作为Runnable被线程执行,也可以作为Future获取Callable的返回值
FutureTask是一个可取消的异步计算,FutureTask实现了Future接口的基本方法,提供了cancel操作,可以查询是否已经完成,并获取最终的计算结果。结果只能在计算完成后获取,get方法具备阻塞等待的功能,一旦计算完成,那么计算就不能再次启动或者取消。
Callable<Integer> callable =new MyCallable();
FutureTask<Integer> future =new FutureTask<Integer>(Callable);
new Thread(future).start();
线程池应用实现
ThreadPoolExecutor:
ThreadPoolExecutor是线程池框架的一个核心类,线程池提供了线程对象的复用机制,并对线程进行统一管理
Executors:
Executors是一个用户创建线程池的工具类。
好了,今天的课程就先总结学习到这里吧!我们下次再见!!!