多线程实现的4种方法及比较
一、多线程触发条件
- 同时执行两个或多个任务
- 有需要等待的任务:用户输入、文件读写、网络操作、搜索等
- 需要一些后台运行的程序
二、多线程实现的四种方法及比较
实现方法 | 实现过程、好处 |
---|---|
继承Thread类 | 1、创建子类,继承Thread类 2、重写run() 3、创建子类对象 4、对象.start() |
实现Runnable方法 | 1、创建实现Runnable方法的类 2、实现run()方法 3、创建Thread对象,将类作参数传过去 4、Thread.start(); 好处: 1、继承Thread类:如果本身就继承的有其他父类,就没办法继承Thread类了,有局限性,通常都会选Runnable方法; 2、实现的方式更适合来处理多个线程共享数据的情况 |
实现Callable接口 | 1、创建一个实现Callable的实现类 2、实现call方法,将此线程需要执行的操作声明在call()中 3、创建FutureTask的对象,将类作参数传过去 4、创建Thread对象,Thread(FutureTask的对象).start() 5、get()获取Callable中call方法的返回值 好处: 1、call()可以有返回值、可抛异常供外部捕获,而run()没有; 2、Callable接口支持泛型:implements Callable< Integer >通过指定泛型,call()方法的返回值就会有类型 |
使用线程池 | 1、提供指定线程数量的线程池 2、执行指定的线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象 3、关闭连接池 好处: 1、便于线程管理 ,提高响应速度, 2、重复利用线程池中线程,不需要每次都创建,降低资源消耗 |
二、多线程实现的四种方法举例
// 继承Thread类
// 主线程
public class thread_test{
public static void main(String[] args){
ThreadTest1 threadTest1 = new ThreadTest1();
ThreadTest2 threadTest2 = new ThreadTest2();
threadTest1.start();
threadTest2.start();
System.out.println("3333");
}
}
// 子线程1
class ThreadTest1 extends Thread {
@Override
public void run() {
System.out.println("11111");
}
}
// 子线程2
class ThreadTest2 extends Thread {
@Override
public void run() {
System.out.println("2222");
}
}
输出
3333
2222
11111
// 实现Runnable方法
public class runnable_test {
public static void main(String[] args){
Thread thread = new Thread(new RunnableTest());
thread.start();
}
}
class RunnableTest implements Runnable{
@Override
public void run() {
System.out.println("111111");
}
}
// 实现Callable接口
//1.创建一个实现Callable的实现类
class NumThread implements Callable {
//2.实现call方法,将此线程需要执行的操作声明在call()中
@Override
public Object call() throws Exception {
return "11111";
}
}
class callable_test {
public static void main(String[] args) {
//3.创建FutureTask的对象,将类作参数传过去
FutureTask futureTask = new FutureTask(new NumThread());
//4.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
new Thread(futureTask).start();
try {
//5.get()获取Callable中call方法的返回值
Object ss = futureTask.get();
System.out.println(ss);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
// 使用线程池
public class Executor_test {
public static void main(String[] args) {
// 1. 提供指定线程数量的线程池
ExecutorService service = Executors.newFixedThreadPool(5);
ThreadPoolExecutor threadPool = (ThreadPoolExecutor) service;
// 设置线程池的属性
threadPool.setCorePoolSize(15); // 核心池的大小
threadPool.setMaximumPoolSize(20); // 最大线程数
// threadPool.setKeepAliveTime(); // 线程没任务时最多保持多长时间后会终止
// 2.执行指定的线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象
threadPool.execute(new executorTest1()); //execute: Runnable接口
threadPool.execute(new executorTest2());
try {
//submit: Callable接口,需要用get获取返回值,顺便捕捉异常
Future<Integer> i = threadPool.submit(new executorTest3());
System.out.println(i.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
;
// 3.关闭连接池
service.shutdown();
}
}
class executorTest1 implements Runnable {
@Override
public void run() {
System.out.println("1111");
}
}
class executorTest2 implements Runnable {
@Override
public void run() {
System.out.println("222");
}
}
class executorTest3 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
return 10;
}
}
四、关于线程调用的方法
run() | 被重写的方法 |
---|---|
start() | 启动线程,调用当前线程run() |
getName()、setName() | 得到、设置线程名字 |
yield() | 释放当前cpu的执行权 |
currentThread() | 返回当前线程 |
join() | 在线程a中调用线程b.join(),让线程a等待线程b执行结束之后再运行,等待时线程a进入阻塞状态 |
sleep(Long millitime) | 睡眠指定毫秒,睡眠时程阻塞状态 |
stop() | 结束线程 |
isAlive() | 是否启动 |
getPriority()、setPriority()) | 优先级 |
五、线程的生命周期
总结
以上就是今天要讲的内容,本文仅仅简单介绍了多线程实现的4种方法及比较的内容,有描述错误的地方请指出,感谢观看。