单例模式(Singleton Pattern):是一种常用的设计模式,主要用于确保一个类在整个应用程序中只有一个实例,并提供一个全局访问点核心作用
常见实现方式
public class Singleton {
//类加载时进行实例化
private static final Singleton hungry = new Singleton();
//全局唯一获取实例的接口
public static Singleton getInstance(){
return hungry;
}
//构造方法私有化
private Singleton(){}
}
特点:
缺点:
class Singleton{
//volatile:禁止指令重排序
private static volatile Singleton lazy = null;
//创建锁对象
private static final Object object = new Object();
//全局唯一获取实例的接口
public static Singleton getInstance(){
//外层if判断:优化,提高性能
if (lazy == null) {
//避免多线程时实例化多个对象
synchronized (object) {
if (lazy == null) {
lazy = new Singleton();
}
}
}
return lazy;
}
//构造方法私有化
private Singleton(){}
}
实现细节:
特点:
缺点:
Java对象初始化流程
Java对象初始化流程(指令重排序后)

特性 | 懒汉模式 | 饿汉模式 |
|---|---|---|
实例化时机 | 第一次使用时 | 类加载时 |
资源消耗 | 节省资源 | 可能浪费资源 |
线程安全 | 需要额外同步机制 | 天然线程安全 |
实现复杂度 | 较复杂 | 简单 |
适用场景 | 实例化开销大,延迟加载 | 实例化开销小,不需要延迟加载 |
生产者/消费者模式(Producer/consumer model):用于协调多个线程或进程之间的任务分配与数据处理。生产者负责生成数据或任务,消费者负责处理这些数据或任务,二者通过共享的缓冲区(队列)进行解耦,避免直接依赖核心作用
class MyBlockingQueue{
private int head = 0;
private int tail = 0;
private int useSize = 0;
private final String[] array;
public MyBlockingQueue(int capacity){
array = new String[capacity];
}
//添加
public synchronized void put(String string) throws InterruptedException {
if (isFull()){
//队列满了,等待消费者消耗元素
this.wait();
}
array[tail] = string;
tail++;
tail = (tail + 1) % array.length;
useSize++;
this.notify();
}
//删除
public String take() throws InterruptedException {
String ret;
synchronized (this) {
if (useSize <= 0) {
//队列空了,等待生产者添加元素.
this.wait();
}
ret = array[head];
head++;
head = (head + 1) % array.length;
useSize--;
this.notify();
}
return ret;
}
//判断是否满了
public boolean isFull(){
return useSize >= array.length;
}
}public class Producer_Consumer_Blog {
public static void main(String[] args) {
MyBlockingQueue queue = new MyBlockingQueue(1000);
Thread thread1 = new Thread(()->{
int n = 1;
while (true){
try {
queue.put(n + "");
System.out.println("生产元素n = " + n);
n++;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
Thread thread2 = new Thread(()->{
while (true){
try {
System.out.println("消费元素n = " + queue.take());
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
thread1.start();
thread2.start();
}
}
定时器(Timer):用于在特定时间间隔或指定时间点执行任务的编程模式,广泛应用于定时任务调度、延迟操作、周期性任务等场景。核心思想是将任务的执行逻辑与时间控制解耦,通过统一的定时器管理多个任务核心作用/特点
标准库Timer构造方法
//1.默认构造方法
//创建一个Timer对象,是一个后台线程,并使用线程的默认名字
public Timer() {
this("Timer-" + serialNumber());
}
//2.指定线程名字的构造方法
//创建一个Timer对象,是一个后台线程,并使用指定的线程名字
public Timer(String name) {
thread.setName(name);
thread.start();
}
//3.指定是否为后台线程的构造方法
//传入true,是后台线程;传入false,是前台线程
public Timer(boolean isDaemon) {
this("Timer-" + serialNumber(), isDaemon);
}
//4.指定线程名字和是否为后台线程的构造方法
public Timer(String name, boolean isDaemon) {
thread.setName(name);
thread.setDaemon(isDaemon);
thread.start();
}标准库Timer的schedule方法
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("延迟三秒执行");
}
};
//使用Date对象来指定具体的执行时间
//new Date(System.currentTimeMillis()+1000表示当前时间等待1000ms
timer.schedule(timerTask,new Date(System.currentTimeMillis()+1000));
}public static void main(String[] args) {
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("延迟三秒执行");
}
};
//当前时间等待1000ms后第一次执行任务
//此后每间隔1000ms就执行一次任务
timer.schedule(timerTask,new Date(System.currentTimeMillis()+1000),1000);
}public static void main(String[] args) {
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("延迟三秒执行");
}
};
//当前时间延迟3000ms后执行
timer.schedule(timerTask,3000);
}public static void main(String[] args) {
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("延迟三秒执行");
}
};
//当前时间延迟3000ms后执行
//此后每间隔3000ms就执行一次任务
timer.schedule(timerTask,3000,3000);
}class MyTask implements Comparable<MyTask>{
private final Runnable runnable;
private final long time;
public MyTask(Runnable runnable,long delay){
this.runnable = runnable;
this.time = System.currentTimeMillis() + delay;
}
public long getTime(){
return this.time;
}
public void run(){
runnable.run();
}
@Override
public int compareTo(MyTask o) {
return (int)(this.time - o.time);
}
}
class MyTime{
private final PriorityQueue<MyTask> queue = new PriorityQueue<>();
public void schedule(Runnable runnable,long delay){
synchronized (this) {
MyTask myTask = new MyTask(runnable, delay);
queue.offer(myTask);
this.notify();
}
}
public MyTime(){
Thread thread = new Thread(() -> {
while (true) {
try {
synchronized (this) {
while (queue.isEmpty()) {
this.wait();
}
MyTask myTask = queue.peek();
long curTime = System.currentTimeMillis();
if (curTime >= myTask.getTime()) {
myTask.run();
queue.poll();
} else {
this.wait(myTask.getTime() - curTime);
}
}
}catch (InterruptedException e){
throw new RuntimeException(e);
}
}
});
thread.setDaemon(true);
thread.start();
}
}
线程池:线程池是一种管理和复用线程的编程模式。它预先创建一定数量的线程,在执行任务需要时,将任务分配给这些线程,从而提高运行效率核心作用:优化多线程任务的执行效率与管理资源特点
标准库线程池构造方法

假设现在有一个线程池:核心线程数2,最大线程数4,等待队列2





public class MyThreadPoolExecutor {
private final int capacity = 1000;
//阻塞队列
private final MyBlockingQueue queue = new MyBlockingQueue(capacity);
private final List<Thread> list = new ArrayList<>();
//创建线程
public MyThreadPoolExecutor(int n){
for (int i = 0; i < n; i++) {
Thread thread = new Thread(()->{
while (true) {
try {
queue.take().run();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
thread.start();
list.add(thread);
}
}
//添加任务
public void submit(Runnable runnable) throws InterruptedException {
queue.put(runnable);
}
public int getCapacity(){
return capacity;
}
//获取线程
public List<Thread> getList() {
return list;
}
}