线程

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 方法已弃用

posted @   半条咸鱼  阅读(45)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示