1、继承的方式(Thread)
public class AAdemo03 {
public static void main(String[] args) {
Mythread mythread = new Mythread();
mythread.setName("线程名");//线程名
mythread.setDaemon(false);//是否设为守护线程
mythread.start();//运行线程
}
}
class Mythread extends Thread{
@Override
public void run() {
//继承的方式实现多线程
}
}
2、实现接口的方式(Runable\Callable)
public class AAdemo03 {
public static void main(String[] args) {
MyRunable task = new MyRunable();
Thread thread = new Thread(task,"线程名");
thread.start();
}
}
class MyRunable implements Runnable{
@Override
public void run() {
//实现Runable的方式
}
}
class MyCallable implements Callable{
@Override
public Object call() throws Exception {
return "实现callable的方式";
}
}
3、线程池的方式
1、线程池讲解
1、线程池工作原理
2、线程池继承实现结构
3、ThreadPoolExcutor类
核心构造方法:![](https://img-blog.csdnimg.cn/direct/647c1098b2f64fdda4ab072efa4de15f.png)
(AbstractExecutorService)抽象类核心方法:
(ExecutorService)接口核心方法:
(Executor)接口核心方法:
核心七大属性:
2、线程池实例
public static void main(String[] args) {
ExecutorService poolExecutor = new ThreadPoolExecutor(10, 10,
60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new NameThreadFactory("线程池"));
poolExecutor.execute(new Runnable() {
@Override
public void run() {
//execute 执行runable
}
});
Future<String> future = poolExecutor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "submit执行 callable";
}
});
}
3、Executors线程工具类
不建议使用这里不做详细介绍
弊端如下:
1)FixedThreadPool和SingleThreadPool:
允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量请求,导致OOM.
2)CachedThreadPool和ScheduledThreadPool:
允许的最大线程数量为Integer.MAX_VALUE,可能会创建大量线程,导致OOM.
4、多线程的问题
1、核心线程数大小怎么设置?
CPU密集型任务:N(CPU核心数量)+1
IO密集型任务:2*N
2、线程池的5种状态
RUNNING: 线程池的初始化状态,可以添加待执行的任务。
SHUTDOWN:线程池处于待关闭状态,不接收新任务仅处理已经接收的任务。
STOP:线程池立即关闭,不接收新的任务,放弃缓存队列中的任务并且中断正在处理的任务。
TIDYING:线程池自主整理状态,调用 terminated() 方法进行线程池整理。
TERMINATED:线程池终止状态。
3、几种拒绝策略
AbortPolicy: 丢弃任务,抛运行时异常。(默认)
CallerRunsPolicy: 执行任务。
DiscardPolicy: 忽视,什么都不会发生。
DiscardOldestPolicy: 从队列中踢出最先进入队列(最后一个执行)的任务。
4、队列workQueue
无界队列、有界队列、同步移交、优先级队列。
5、线程锁
1、synchronized代码块
2、同步方法
3、Lock
自旋锁的定义:
指当一个线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。
自旋锁的优点:避免线程切换带来的开销
白话文:我把CPU占用着,用完才释放
自适应自旋锁(自旋次数动态变化)
自旋次数由什么决定?
由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定
白话文:参考上次的自旋时间
6、计数器
CyclicBarrier和CountDownLatch