一、基本概念
* 进程:操作系统资源分配的最小单位,进程中的事情需要按照一定顺序执行 * 线程:程序执行的最小单位,系统独立调度和分派CPU的基本单元 * 多线程:创建多个线程执行,充分利用cpu资源,提高系统的执行效率
二、创建方式
* 实现Runnable接口 * 继承Thread类 * CallAble * 线程池
1、实现Runnable接口
优点:实现接口,对于Java单继承的限制有优势,并且线程池只接受Runnable类型,不接受Thread类型
缺点:编程复杂度比Thread高
//编写类实现Runnable接口,重载run()方法
class RunnableTest implements Runnable{
@Override
public void run() {
System.out.println("Runnable接口的线程执行---------");
}
}
/** main()方法调用 */
public static void main(String[] args) throws Exception {
RunnableTest runnableTest = new RunnableTest();
new Thread(runnableTest).start();
}
2、继承Thread类
优点:编写相对简单,访问当前线程直接使用this就可以获得当前线程
缺点:Java单继承,继承Thread之后无法继承其他类
//编写类继承Thread类,重写run()方法
class ThreadTest extends Thread{
@Override
public void run() {
System.out.println("Thread类的线程执行------------");
}
}
//main()方法调用
public static void main(String[] args) throws Exception {
new ThreadTest().start();
}
3、实现Callable接口
优点:有返回值,可以去除单继承的限制,可以抛出异常
缺点:复杂度高
/*** 创建类实现CallAble接口,重载call()方法 */
class CallAbleTest implements Callable{
@Override
public Object call() throws Exception {
return test();
}
public String test(){
System.out.println("CallAble接口执行");
return "CallAble接口返回结果";
}
}
public static void main(String[] args) throws Exception {
CallAbleTest callAbleTest = new CallAbleTest();
FutureTask futureTask = new FutureTask<String>(callAbleTest);
new Thread(futureTask).start();
/*** get()方法会阻塞主线程,等子线程执行返回,主线程开始执行 */
String res = (String) futureTask.get();
System.out.println(res);
}
/***执行结果**/
CallAble接口执行
CallAble接口返回结果
4、线程池
java提供多种线程池创建方式,以ThreadPoolExecutor为例
执行流程:无论有没有任务,线程池中都保持核心线程数;如果核心线程满了,接下来的任务需要创建最大线程;当最大线程也满了之后,进入阻塞队列;队列也满了之后,即已经达到线程池最大数量,多余的任务会触发拒绝策略。
/***
* 线程池核心参数
* 核心线程数,无论线程是否有任务,都是存在那么多线程
* 最大线程数,当核心线程不够时,可增加的线程数量
* 核心线程之外的线程存活时间
* 核心线程之外的线程存活时间单位
* 工作任务队列
* 拒绝策略(抛异常等等)
*/
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
10,
20,
10,
TimeUnit.DAYS,
objects
);
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(423432);
}
};
threadPoolExecutor.execute(runnable);