线程状态

线程状态

在多线程编程中,线程可以处于不同的状态,这些状态反映了线程在其生命周期中的不同阶段和行为。Java中的线程状态通常有以下几种:

  1. New(新建)
    • 当线程对象被创建但还没有调用 start() 方法启动线程时,线程处于新建状态。
  2. Runnable(可运行)
    • 处于可运行状态的线程可能正在运行,也可能正在等待系统资源(如处理器时间)。
  3. Blocked(阻塞)
    • 线程因为某些原因放弃了 CPU 使用权,暂时停止运行。例如,线程在等待某个监视器锁(通过 synchronized 关键字实现的同步块)时会进入阻塞状态。
  4. Waiting(等待)
    • 线程因为调用了 Object.wait()Thread.join() 或者 LockSupport.park() 方法而进入等待状态。线程会一直等待,直到其他线程调用相应对象的 notify()notifyAll() 方法或者线程中断、超时。
  5. Timed Waiting(计时等待)
    • 线程因为调用了带有超时参数的 Object.wait(timeout)Thread.join(timeout)Thread.sleep(timeout) 或者 LockSupport.parkNanos(timeout) 方法而进入计时等待状态。线程会在一定时间内等待,超过时间后会自动恢复到 Runnable 状态。
  6. Terminated(终止)
    • 线程已经执行完毕,处于终止状态。可以通过调用 Thread.isAlive() 方法来判断线程是否已经终止。线程中断或结束,一旦进入死亡状态就不能再次启动

这些状态是通过 Java 虚拟机和操作系统共同管理和维护的。在编写多线程程序时,理解这些状态是非常重要的,可以帮助开发人员正确地控制和监视线程的行为,避免出现死锁、资源竞争等问题。

线程方法

方法 说明
setPriority(int newPriority) 更改线程的优先级
static void sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠
void join() 等待该线程终止
static void yield() 暂停当前正在执行的线程对象,并执行其他线程
void interrupt() 中断线程,禁用
boolean isAlive() 测试线程是否处于活动状态

停止线程

使用标志位进行终止变量flag = false

public class ThreadStop implements Runnable {
// 通过设置标志位来终止变量
    private boolean flag = true;

    @Override
    public void run() {
        int i = 0;
        while(flag){
            System.out.println("run...Thread"+i++);
        }
    }

    // 设置公开方法来停止线程,转换标志位
    public void stop(){
        this.flag = false;
    }

    public static void main(String[] args) {
        ThreadStop threadStop = new ThreadStop();
        new Thread(threadStop).start();
        for (int i = 0; i < 1000; i++) {
            System.out.println(i);
            if (i == 900) {
                threadStop.stop();
                System.out.println("该停止了");
            }
        }
    }
}

线程休眠

sleep(时间)指定当前线程阻塞的毫秒数;sleep(1000),阻塞1s

sleep时间达到后线程进入就绪状态

sleep可以模拟网络延时,倒计时等等;

每个对象都有一个锁,sleep不会释放锁

import java.text.SimpleDateFormat;
import java.util.Date;
public class ThreadSleep implements Runnable {
    @Override
    public void run() {
        int i = 10;
        while (i >= 0) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(i--);
        }
    }
    public static void main(String[] args) throws InterruptedException {
//        ThreadSleep ts = new ThreadSleep();
////        new Thread(ts).start();
        // 获取系统当前时间
        Date CurrentTIme = new Date(System.currentTimeMillis());
        while (true){
            Thread.sleep(1000);
            System.out.println(new SimpleDateFormat("HH:mm:ss").format(CurrentTIme));
            CurrentTIme = new Date(System.currentTimeMillis());
        }
    }

线程礼让

礼让线程,让当前正在执行的线程暂停,但不阻塞

让cpu重新调度,但不一定成功,看cpu心情

public class ThreadYield implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"线程开始执行");
        Thread.yield();
        System.out.println(Thread.currentThread().getName()+"线程结束执行");
    }

    public static void main(String[] args) {
        ThreadYield t1 = new ThreadYield();
        ThreadYield t2 = new ThreadYield();
        new Thread(t1,"a").start();
        new Thread(t2,"b").start();
    }
}

线程合并

Join合并线程

public class ThreadJoin implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("VIP Com! "+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadJoin threadJoin = new ThreadJoin();
        Thread thread = new Thread(threadJoin);


        for (int i = 0; i < 1000; i++) {

            if (i == 400) {
                // 这里start最好写在if里,才能体现join的强势,必须等join的线程走完才能运行其他线程
                thread.start();
                thread.join();
            }
            System.out.println("main "+i);
        }
    }
}

线程优先级

优先级用数字表示,范围从1-10

  • Thread.MIN_PRIORITY = 1
  • Thread.MAX_PRIORITY = 10
  • Thread.NORM_PRIORITY = 5

使用以下方式改变或获取优先级

  • getPriority(), setPriority(int xxx)

优先级的设定建议在start()调度前

优先级低,只意味着获得调度的概率低,并不是优先级低就不会被调用了,全看cpu调度

守护线程

daemon

  • 线程分为用户线程与守护线程
  • 虚拟机必须确保用户线程执行完毕
  • 虚拟机不用等待守护线程执行完毕
  • 如,后台记录操作日志,监控内存,垃圾回收等待..
package com.syzCodeGround.Demo04_Status;

public class ThreadDaemon {
    public static void main(String[] args) {
        God god = new God();
        Thread gThread  = new Thread(god);
        gThread.setDaemon(true);
        gThread.start();

        new Thread(new You()).start();
    }
}

class You implements Runnable {
    public void run() {
        for (int i = 0; i < 365; i++) {
            System.out.println("nb,又活一年");
        }
        System.out.println("丸辣!");
    }
}

class God implements Runnable {
    public void run() {
        while (true){
            System.out.println("God bless you");
        }
    }
}
posted @ 2024-08-04 09:15  SyzTak  阅读(10)  评论(0)    收藏  举报