线程
1、进程:运行中的程序,程序的一次执行过程,或正在运行的一个程序,是动态过程
2、线程:由进程创建,是进程的一个实体,一个进程可以有多个线程
(1)单线程:同一时刻,只允许执行一个线程
(2)多线程:同一时刻,可以执行多个线程
3、并发、并行同时存在
(1)并发:同一时刻,多个任务交替执行,即单核 CPU 实现多任务
(2)并行:同一时刻,多个任务同时执行,即多核 CPU 实现多任务
4、全部线程结束,进程才结束,main 线程启动子线程,主线程不会阻塞,它们是交替执行
Java 创建线程
1、继承 Thread 类
(1)该类可以当作线程使用
(2)重写 run 方法,实现需要的业务逻辑
(3)Thread 类实现 Runnable 接口的 run 方法
(4)该类创建对象后,调用 start 方法启动线程
对象名.start();
2、实现 Runnable 接口
(1)解决 Java 单继承机制的问题
(2)重写 run 方法,实现需要的业务逻辑
(3)Runnable 接口没有 start 方法,只有 run 方法
public interface Runnable {
public abstract void run();
}
(4)使用代理模式:创建 Thread 对象,把实现 Runnable 接口的类对象传入 Thread 对象,再由 Thread 对象调用 strat 方法
Thread thread = new Thread(对象名);
thread.start();
线程启动
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
private native void start0();
(1)核心方法:start0,是本地方法,JVM 调用,底层由 C / C++ 实现
(2)start 调用 start0 后,该线程不会立刻执行,只是将线程变成可运行状态,由 CPU 统一调度线程执行时机
线程终止
1、线程完成任务,自动退出
2、通知方式:使用变量控制 run 方法的退出,以此停止线程
(1)在类中设置变量,提供 set 方法
(2)main 线程调用 set 方法修改该变量以停止子线程
Thread 类
1、线程优先级
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
2、将此线程的名称更改为等于参数 name
public final synchronized void setName(String name)
3、返回此线程的名称
public final String getName()
4、调用 start0,创建新进程
public synchronized void start()
5、调用线程对象重写的 run 方法
public void run() {
if (target != null) {
target.run();
}
}
6、更改此线程的优先级
public final void setPriority(int newPriority)
7、 返回此线程的优先级
public final int getPriority()
8、使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性
public static native void sleep(long millis) throws InterruptedException;
9、导致正在执行的线程以指定的毫秒数加上指定的纳秒数来暂停(暂时停止执行),这取决于系统定时器和调度器的精度和准确性
public static void sleep(long millis, int nanos) throws InterruptedException
10、调用核心方法:interrupt0,中断这个线程,没有真正结束线程,用于中断正在休眠线程,当前线程 sleep 状态被清除,抛出 InterruptedException
public void interrupt()
private native void interrupt0();
线程中断
1、当前线程愿意让出当前使用的 CPU,调度程序可以自由地忽略这个提示,即不一定成功让出
(1)让当前正在运行的线程回到就绪状态,以允许具有相同优先级的其他线程获得运行的机会
(2)因此,使用 yield() 的目的是让具有相同优先级的线程之间能够适当的轮换执行,但是,实际中无法保证 yield() 达到让步的目的,因为,让步的线程可能被线程调度程序再次选中
public static native void yield();
2、线程插队,一旦插队成功,则优先执行插入线程的所有任务,直到完成
public final void join() throws InterruptedException {
join(0);
}
public final synchronized void join(long millis) throws InterruptedException
public final synchronized void join(long millis, int nanos) throws InterruptedException
守护线程
1、用户线程 / 工作线程
2、守护线程:为工作线程服务,当所有工作线程结束,守护线程结束
3、应用:垃圾回收机制
4、设置
(1)将此线程标记为守护线程或用户线程,当运行的唯一线程都是守护进程线程时,Java虚拟机将退出,线程启动前必须调用此方法
(2)daemon 默认为 false,为用户线程;设置为 true 时,为守护线程
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
(3)守护线程在工作线程中设置
线程七种状态
1、NEW:尚未启动的线程
2、RUNNABLE:在 JVM 中执行的线程
(1)Ready(内核态)
(1)Running(内核态)
3、BLOCKED:被阻塞等待监视器锁定的线程
4、WAITING:正在等待另一个线程执行特定动作的线程
5、TIMED_WAITING:正在等待另一个线程执行动作到指定时间
6、TERMINATED:已退出
线程生命周期
注:wait、notify、notifyAll 是 Object 类普通方法,join 是 Thread 类普通方法,其余为静态方法
1、new(创建线程)-> NEW -> start() -> RUNNABLE
2、Ready -> 线程被调度器选中执行 -> Runnig
3、Runnig -> 线程被挂起 / Thread.yeid -> Ready
4、RUNNABLE -> 被线程调度器执行 -> wait() / join() / LockSupport.park() -> WAITING -> notify() / notifyAll() / LockSupport.unpark() -> RUNNABLE
5、RUNNABLE -> wait(time) / join(time) / LockSupport.parkNanos() / LockSupport.parkUntil() -> TIMED_WAITING -> 时间结束 -> RUNNABLE
6、RUNNABLE -> 等待进入同步代码块的锁 -> BLOCKED -> 获得锁 -> RUNNABLE
7、RUNNABLE -> TERMINATED
线程同步机制
1、使用同步访问,在多线程情况下,保证数据在任何同一时刻,最多一个线程访问,保证数据完整性
2、互斥锁
(1)synchronized 关键字与对象的互斥锁联系
(2)局限性:降低程序执行效率
(3)同步代码块(建议):范围越小,效率越高
synchronized(对象) {
需要被同步的代码;
}
(4)非静态锁,默认锁对象:this,锁对象可为 this,也可以为其他对象
(5)静态锁,默认锁对象:当前类.class,即当前类本身
(6)同步方法:方法声明 synchronized
访问修饰符 synchronized 返回数据类型 方法名(形参列表) {
同步方法体;
}
3、线程死锁:多个线程都占用对方锁资源,导致死锁
4、释放锁的情况
(1)同步代码执行结束
(2)break / return
(3)出现未处理的 Error / Exception,导致异常结束
(4)执行线程对象的 wait 方法,暂停当前线程
5、不会释放锁的情况
(1)调用 Thread.sleep、Thread.yield 方法,暂停当前线程
(2)其他线程调用该线程的 suspend 方法,将该线程挂起;suspend、resume 方法已弃用
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战