Java笔记——多线程总结

tech2026-06-11  1

创建线程的三种方式

public class MyThread extends Thread { @Override public void run() { } } new MyThread().start(); new Thread(new Runnable() { @Override public void run() { } }).start(); FutureTask<String> task = new FutureTask<String>(new Callable<String>() { @Override public String call() throws Exception { return null; } }); new Thread(task).start(); try { String result = task.get(); // 阻塞式取值 } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }

线程常用方法

thread.isAlive(); // 判断线程是否活动(是否已经start并且尚未结束) thread.join(); // 当前线程会等待thread执行返回 thread.setDaemon(true); // 设置为后台线程(当只有后台线程时,进程会结束) thread.setPriority(Thread.MAX_PRIORITY); // 优先级 Thread.yield(); // 暂停一下

两种线程同步方式

同步监视器

同步监视器 synchronized 同步代码块、同步方法 sleep、yield 不会释放同步锁 wait 会释放同步锁(wait需要synchronized括号里的那个东西来调用,它是一个Object方法) wait、notify、notifyAll

同步锁(ReentrantLock、ReentrantReadWriteLock)

简单用法:

private final ReentrantLock lock = new ReentrantLock(); public void dosomething() { lock.lock(); // tryLock、lockInterruptibly try { // TODO } finally { lock.unlock(); } }

带条件用法:

private final ReentrantLock lock = new ReentrantLock(); private final Condition condition = lock.newCondition(); public void dosomething() { lock.lock(); try { if (true) // 根据业务替换其它条件 { condition.await(); } else { condition.signalAll(); } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }

阻塞队列(BlockingQueue)

阻塞队列(BlockingQueue)可用于一个线程存,一个线程取的情况

常用实现类:

ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(2);

线程组 ThreadGroup 用于管理线程,它可以是个树组合(因为有getParent方法)

常用方法

        threadGroup.activeCount();         threadGroup.interrupt();         threadGroup.isDaemon();         threadGroup.setDaemon(true);

线程池常规用法

ExecutorService pool = Executors.newFixedThreadPool(5); pool.execute(new Runnable() { @Override public void run() { } }); Future<String> result = pool.submit(new Callable<String>() { @Override public String call() throws Exception { return null; } }); try { if (result.isDone()) result.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } pool.shutdown();

其它线程池

        Executors.newCachedThreadPool();         Executors.newFixedThreadPool(5);         Executors.newSingleThreadExecutor();

        Executors.newScheduledThreadPool(5);         Executors.newSingleThreadScheduledExecutor();

        Executors.newWorkStealingPool(Runtime.getRuntime().availableProcessors());         Executors.newWorkStealingPool();

ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

int corePoolSize : 核心线程数

int maximumPoolSize : 最大线程数

long keepAliveTime, TimeUnit unit : 非核心线程闲置的超时时间(超时将被回收)

    executor.allowCoreThreadTimeOut(true); // 可将超时同时作用到核心线程

BlockingQueue<Runnable> workQueue : 任务队列

ThreadFactory threadFactory : 线程工厂

RejectedExecutionHandler handler : 饱和策略

    new ThreadPoolExecutor.AbortPolicy(); // 抛出异常(默认)     new ThreadPoolExecutor.CallerRunsPolicy(); // 用调用者所在线程处理     new ThreadPoolExecutor.DiscardPolicy(); // 丢弃新任务     new ThreadPoolExecutor.DiscardOldestPolicy(); // 挤掉一个任务

示例用法

private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 50, 5, TimeUnit.SECONDS, new ArrayBlockingQueue(5), new ThreadPoolExecutor.DiscardOldestPolicy());

线程池默认是空的(可调用 prestartAllCoreThreads 提前启动核心线程),若持续有任务进来,会先填满 5 个核心线程,然后进任务队列,任务队列满了,会继续创建线程直到 50 个,再然后会执行饱和策略

ForkJoinPool 用于分解任务

一般用法

public class PrintTask extends RecursiveAction { private int start, end; public PrintTask(int start, int end) { this.start = start; this.end = end; } @Override protected void compute() { if (end - start < 50) { for (int i = start; i < end; i++) { LOG.v(Thread.currentThread().getName() + " - " + i); } } else { int middle = (start + end) / 2; PrintTask left = new PrintTask(start, middle); PrintTask right = new PrintTask(middle, end); left.fork(); right.fork(); } } } 调用示例 ForkJoinPool pool = new ForkJoinPool(); pool.submit(new PrintTask(0, 300)); pool.shutdown();

带返回值的用法

public class PrintTask extends RecursiveTask<Integer> { private int start, end; public PrintTask(int start, int end) { this.start = start; this.end = end; } @Override protected Integer compute() { int sum = 0; if (end - start < 50) { for (int i = start; i < end; i++) { sum += i; } } else { int middle = (start + end) / 2; PrintTask left = new PrintTask(start, middle); PrintTask right = new PrintTask(middle, end); left.fork(); right.fork(); sum = left.join() + right.join(); } return sum; } } 调用示例 ForkJoinPool pool = new ForkJoinPool(); ForkJoinTask<Integer> result = pool.submit(new PrintTask(0, 300)); try { LOG.v("result : " + result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } pool.shutdown();

ThreadLocal 用于为每个线程生成数据副本

private ThreadLocal<String> data = new ThreadLocal<>(); public void func() { data.get(); data.set("some"); }

将集合包装为线程安全系列方法

Collections.synchronizedXxx()

 

 

 

 

最新回复(0)