Java多线程
线程的创建及使用
Java创建线程有两种方式:
- 继承Tread类
public class TestDemo extends Thread{ @Override public synchronized void start() { super.start(); } @Override public void run() { super.run(); } }
常用方法:
- Thread() 构造一个线程,可指定线程目标或创建新的线程
- void start() 启动线程,调用关联Runnable的run方法,且线程将并发执行
- static void sleep(long millis) 休眠给定的毫秒数
- void interrupt() 发送中断请求,若线程被sleep阻塞,将会抛出异常InterruptedException
- static boolean interrupted()和boolean isInterrupted() 两个方法非常类似,用于检测线程是否被中断,前者是一个静态方法,会将线程的中断状态重置为false,后者则不会
- static Thread currentThread() 返回当前的线程对象
线程调度方法:
- void join() 加入指定线程,并等待其终止
- static void yield() 线程让出处理器,等待再次调度,调度器会寻找优先级相同或更高的线程
- void setPriority(int newPriority) 设置线程优先级,调度器会优先选择高优先级的线程,子类默认继承父类优先级
- void setDaemon(boolean) 设置守护线程,为其他线程服务,且不应该去访问固有资源,该方法炫耀在线程启动前调用
- 实现Runnable接口
public class TestDemo extends Runnable{ @Override public void run() {} }
只有一个run方法,用于执行线程逻辑任务,但不要直接调用Runnable或Tread的run方法,否则将会是一个普通方法,不会启动线程
同步:
两种不同的实现方法
- Lock和Condition对象
private Lock lock; private Condition condition; public TestDemo(){ lock= new ReentrantLock(); condition= lock.newCondition(); } public void method(){ lock.lock(); try{ method body }finally { lock.unlock(); } }
Lock锁:
java提供一个关键字synchronized实现线程并发访问数据,该关键字会提供一个”锁“及相关的条件,一旦有线程获得锁,其他线程只能等待锁被释放。锁是可重入的,锁保持一个持有计数,使得持有锁的代码可调用其他的锁
- void lock() 获取锁
- void unlock() 释放锁
- ReentrantLock() 构建一个可以被用来保护临界区的可重入锁,可加入boolean参数构建带公平策略的锁,会优先选择等待时间最长的线程,但会降低性能
可以调用才有超时参数的tryLock,线程可以离开去做其他事情
条件对象:
一个锁可以有一个或多个条件对象,通过newCondition获取,当发现线程不满足相应条件时,调用条件对象的await()方法进入等待集,没办法自己重新激活,直到另一线程调用同一条件的signalAll()方法,也可提供超时参数
- Condition newCondition() 获取锁对象
- void await() 将线程放入等待集
- void signalAll()/signal() 解除等待集中的所有线程/某个随机线程
- synchronized关键字
public synchronized void method(){}
每个方法都有一个内部锁,若用synchronized关键字声明,则线程必须获取内部的对象锁,内部锁只有一个相关条件,其中wait()方法等价于await(),notifyAll()/notify()等价于signalAll()/signal(),这几个方法是Object的final方法,特别的是,静态方法也可被synchronized关键字声明,这将导致类的class对象被锁住,因此其他线程不能调用同一个类的任何同步静态方法
- void wait() 将线程放入等待集
- void notifyAll()/notify() 解除等待集中的所有线程/某个随机线程
同步阻塞:通过同步阻塞可获取对象锁
private Object object=new Object(); public void method(){ synchronized (object){ method bady } }
Volatile关键字:
为实例域的同步访问提供了一种免锁机制,如果声明一个域为volatile,那么编译器和虚拟机就知道该域可能被另一个线程并发更新的,但volatile变量不能提供原子性
final变量:
除了加锁或使用volatile修饰符,还可使用final安全访问一个共享域
读写锁:
通过ReentrantReadWriteLock创建锁对象,允许读者线程共享访问,但写者线程依旧必须互斥访问
private ReentrantReadWriteLock rrw=new ReentrantReadWriteLock(); private Lock rlock=rrw.readLock(); private Lock wlock=rrw.writeLock(); public void method(){ rlock.lock(); try{} finally { rlock.unlock(); } wlock.lock(); try{} finally { wlock.unlock(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix