线程
线程的创建
- 继承类
Thread
,重写public void run()
- 实现接口
Runnable
,重写public void run()
- 实现接口
Callable<V>
,重写public V call()
,构建FutureTask<V>(callable)
,新建线程,如new Thread(futureTask).start()
,示例:
public static void main(String[] args){
Callable<String> callable = new Callable<>(){
public String call(){
Thread.sleep(500);//futureTask get() 阻塞当前线程
return "callable";
}
};
FutureTask<String> futureTask = new FutureTask<String>(callable);
new Thread(futureTask).start();
try{
Thread.sleep(100);
System.out.println(futureTask.get());
}catch(InterruptedException | ExecutionException e){
e.printStackTrace();
}
}
FutureTask
实现了接口 Runnable
和 Future
,也就是当线程调用 run()
方法时,FutureTask
内部调用 Callable
的 call()
,执行后返回值通过 set(V result)
保存,等待 Future
调用(或不使用)。使用 Callable
方式创建的线程有返回值可抛异常,通过 FutureTask
的 get()
方法获取,当线程未执行完成时,阻塞当前线程直到子线程完成并返回结果,也可使用 get(long timeout, TimeUnit unit)
设置超时时间,避免长时间阻塞当前线程。
线程基本属性
- 优先级
setPriority
,0-10,10优先级最高 - sleep() 进入休眠,不放弃所有权
yield() 放弃
1.让出优先权,告诉当前正在执行的线程把运行机会给线程池中优先级相同的其他线程
2.但不能保证当前线程有运行状态迅速转换成可运行状态
3.只能使一个线程由运行状态转为可运行状态,而不是等待或者阻塞join() 阻塞当前线程,等待线程完成,类似同步作用,
join()
与join(0)
一致,表示无限长时间,也可传非0时间,表示等待时间长度- interrupt() 中断当前线程,如果线程处于
wait(),join(),sleep()
状态,中断标志被清除,触发InterruptedException
,如果是 I/O 操作,则触发ClosedByInterruptException
- stop() 停止线程,过时方法,不安全
- isAlive() 是否存活,已启动未死亡
- setDaemon() 设置守护线程,true:守护线程,false:用户线程,应在启动前设置,如果在守护线程中创建,该线程也是守护线程。当系统剩下所有线程都为守护线程,jvm 结束,守护线程与系统共存亡,优先级比较低,用于为系统中的其它对象和线程提供服务,参考垃圾回收器
线程的复用 – 线程池
线程的执行过程:创建(t1) -> 运行(t2) -> 销毁(t3),总时间 T = t1 + t2 + t3
如果 t1 +t3 >> t2 ,那么频繁创建新线程将会浪费时间在线程的创建和销毁,而线程池技术的出现缩短或调整 t1 t3 占用时间,同时重用已完成线程资源,减少线程的创建、销毁过程,提高工作任务的执行效率。
线程池
- JAVA 在线程池构造中使用
Executors
默认实现了四种线程池,分别是:
newFixedThreadPool(int nThreads)
固定线程数量线程池newSingleThreadExecutor()
单工作线程池newCachedThreadPool()
缓存线程池newScheduledThreadPool(int corePoolSize)
可定时、周期运行的线程池
其本质是通过一个静态工厂类 Executors
创建线程池 ThreadPoolExecutor
使用默认参数构造,降低线程池的使用门槛。
public ThreadPoolExecutor(int corePoolSize,//使用核心
int maximumPoolSize,//线程池最大数量
long keepAliveTime,//线程存活时间
TimeUnit unit,//时间单位
BlockingQueue<Runnable> workQueue,//队列
ThreadFactory threadFactory//线程创建工厂 ) {
}
- 使用
ThreadPoolExecutor
构造适合自己工厂的线程池 - 通过顶级接口
Executor
中的void execute(Runnable command)
方法添加任务 - 也可以通过接口
ExecutorService
中的submit(...)
增加任务,其中Callable<V>
任务使用submit(Callable<T> task)
增加至线程队列,并增加了线程池的几个操作方法
shoutdown()
暂停接收新任务,不会停止运行中的线程,等待队列中任务完成,关闭线程池shoutdownNow()
暂停接收新任务,中断运行中的线程,将等待队列中的线程返回,清除等待队列中任务,关闭线程池awaitTermination(long timeout, TimeUnit unit)
阻塞,直到所有任务完成,或发生超时,或当前线程被中断,已先发生为准,true:所有任务执行完毕,false:超时