文章目录
前言
大部分截图来自于javaguide、库森和路人张,本人只做一些阅读补充
javaguide地址
库森地址
路人张来自公众号面经pdf
视频课程学习
学习juc部分视频建议
黑马程序员全面深入学习Java并发编程,JUC并发编程全套教程
视频总结
线程的生命周期及五种基本状态:
sleep()方法和wait()方法区别和共同点?
Java中守护线程和用户线程的区别?
什么是ThreadLocal?有哪些应用场景?
ThreadLocal原理和内存泄露?
说说并发与并行的区别?
为什么用线程池?解释下线程池参数?
线程池的执行流程
Java创建多线程的方式,区别
● 继承Thread类创建线程,首先继承Thread类,重写run()方法,在main()函数中调用子类实实例的start()方法。
public class ThreadTest{
public static void main(String[] args) {
ThreadDemo demo = new ThreadDemo();
demo.start();
System.out.println(Thread.currentThread().getName()+"main()方法指向结束");
}
}
class ThreadDemo extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"run()方法真在执行");
}
}
输出结果
main main()方法指向结束
Thread-0 run()方法真在执行
● 实现Runnable接口创建线程:首先创建实现Runnable接口的类RunnableDemo,重写run()方法;创建类RunnableDemo的实例对象runnab1 eDemo,以runnableDemo作为参数创建Thread对象,调用Thread对象的start()方法。
public class RunnableTest {
public static void main(String[] ars){
RunnableDemo runnabledemo = new RunnableDemo();
Thread thread = new Thread(runnabledemo);
thread.start();
System.out.println(Thread.currentThread().getName()+" main()方法执行完成");
}
}
class RunnableDemo implements Runnable{
public void run() {
System.out.println(Thread.currentThread().getName()+" run()方法正在运行");
}
}
结果
main main()方法执行完成
Thread-0 run()方法正在运行
● 使用Callable和Future创建线程:1.创建Callable接口的实现类CallableDemo,重写cal1()方法。
2.以类Cal1ableDemo的实例化对象作为参数创建FutureTask对象。3.以FutureTask对象作为参数创建Thread对象。4.调用Thread对象的start()方法。
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* @Author ljm
* @Date 2022/2/25 11:10
* @Version 1.0
*/
public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<Integer> futureTask = new FutureTask<Integer>(new CallableDemo());
Thread thread = new Thread(futureTask);
thread.start();
System.out.println("返回结果 "+futureTask.get());
System.out.println(Thread.currentThread().getName()+" main()方法执行完成");
}
}
class CallableDemo implements java.util.concurrent.Callable<Integer> {
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() +" call()方法执行中");
return 0;
}
}
返回结果
Thread-0 call()方法执行中
返回结果 0
main main()方法执行完成
● 使用线程池例如用Executor框架:Executors可提供四种线程池,分别为:
newcachedThreadPoo1创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPoo1创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newscheduledThreadPoo1创建一个定长线程池,支持定时及周期性任务执行。
newsingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。
下面以创建一个定长线程池为例进行说明.
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @Author ljm
* @Date 2022/2/25 11:19
* @Version 1.0
*/
public class TestFixedThreadPool {
public static void main(String[] args) {
//创建一个可用的固定线程数的线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
//创建Runnable接口对象,Thread对象当然也实现了Runnable接口
ThereadDemo t1 = new ThereadDemo();
ThereadDemo t2 = new ThereadDemo();
ThereadDemo t3 = new ThereadDemo();
ThereadDemo t4 = new ThereadDemo();
ThereadDemo t5 = new ThereadDemo();
//将线程放到线程池中执行
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
//关闭线程池
pool.shutdown();
}
}
class ThereadDemo extends Thread{
public void run() {
System.out.println(Thread.currentThread().getName()+" 正在执行");
}
}
结果显示
pool-1-thread-1 正在执行
pool-1-thread-2 正在执行
pool-1-thread-1 正在执行
pool-1-thread-2 正在执行
pool-1-thread-1 正在执行
runable和callable有什么区别?
相同点:
- 两者都是接口
- 两者都需要调用Thread.start启动线程
不同点: - callable的核心方法是call()方法,允许有返回值,runnable的核心方法是run()方法,没有返回值
- call()方法可以抛出异常,但是run()方法不行
- callable和runnable都可以用于executors,thread类只支持runable。