java多线程——常用方法

一、常用方法

方法说明
start()启动一个新线程,每个线程只能调用一次
run()新线程启动后会调用的方法
join()等待线程结束
getId()获取线程唯一ID
get/setName()获取/修改线程名
get/setPriority()获取/修改线程优先级
getState()获取线程状态
isAlive()判断是否存活
interrupt()打断线程,设置打断标记为true
interrupted判断当前线程是否被打断,判断完后会清除打断标记
isInterrupted()判断是否被打断,判断完后不会清除打断标记
currentThread()获取当前正在执行的线程
sleep(long n)休眠n毫秒
yield()提示线程调度器让出当前线程对CPU的使用

二、start与run

直接调用run()方法不使用start()方法不会启动新线程执行工作,全由main线程完成

@Slf4j(topic = "c.Test1")
public class Test1 {
    public static void main(String[] args) {
        Thread thread = new Thread("thread1") {
            @Override
            public void run() {
               log.debug("xxx");
            }
        };
        // 不会启动新线程
        thread.run();
        log.debug("kkk");
    }
}

三、sleep与yield

  • sleep
  1. 调用sleep会让线程从Running进入Timed Waiting(阻塞)状态
  2. 其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException
  3. 睡眠结束后的线程未必会立刻得到执行
  4. 建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性
  • yield
  1. 调用 yield 会让当前线程从 Running 进入 Runnable(就绪)状态,然后调度执行其它线程
  2. 具体的实现依赖于操作系统的任务调度器

四、join

@Slf4j(topic = "c.Test1")
public class Test1 {
    private static int a = 0;
    public static void main(String[] args) throws InterruptedException {
        log.debug("开始");
        Thread thread = new Thread(() -> {
            log.debug("开始");
            try {
                Thread.sleep(10);
                a = 10;
                log.debug("结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread1");

        thread.start();
        // 等待结束,完成赋值操作
        thread.join();
        log.debug("a={}",a);
        log.debug("结束");
    }
}

五、interrupt

分两种情况

  • 情况一:打断阻塞状态的线程sleep,wait,join。isInterrupted为false

    @Slf4j(topic = "c.Test1")
    public class Test1 {
        public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread(() -> {
                log.debug("开始");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "thread1");
    
            thread.start();
            Thread.sleep(2000);
            // 打断
            thread.interrupt();
            // false
            log.debug("{}",thread.isInterrupted());
        }
    }
    
  • 情况二:打断正常状态线程,idInterrupted为true。当mian线程调用打断命令时,thread1线程仍会继续运行,需要在thread1内部退出线程。

    @Slf4j(topic = "c.Test1")
    public class Test1 {
        public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread(() -> {
                while (true){
                    // 获取当前线程的打断标记状态
                    boolean interrupted = Thread.currentThread().isInterrupted();
                    if (interrupted){
                        log.debug("打断了");
                        break;
                    }
                }
            }, "thread1");
    
            thread.start();
            Thread.sleep(1000);
            // 打断
            thread.interrupt();
            // true
            log.debug("{}",thread.isInterrupted());
        }
    }
    
  • 两阶段终止模式
    在这里插入图片描述

    @Slf4j(topic = "c.Test1")
    public class Test1 {
        public static void main(String[] args) throws InterruptedException {
            TwoPhaseTermination twoPhaseTermination = new TwoPhaseTermination();
            twoPhaseTermination.run();
            Thread.sleep(2000);
            twoPhaseTermination.stop();
        }
    }
    @Slf4j(topic = "c.Test1")
    class TwoPhaseTermination{
        private Thread thread;
    
        public void run(){
            thread = new Thread(() -> {
                // 当前线程
                Thread current = Thread.currentThread();
                while (true){
                    if (current.isInterrupted()) {
                        log.debug("料理后事...");
                        break;
                    }
                    try {
                        // 情况一
                        Thread.sleep(500);
                        // 情况二
                        log.debug("执行监控");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        // 由于情况一会将打断标记设置为false,所以需要重新设置打断标记
                        current.interrupt();
                    }
                }
            }, "thread1");
        thread.start();
        }
    
        public void stop(){
            // 打断操作
            thread.interrupt();
        }
    }
    

六、守护线程

默认情况下,Java 进程需要等待所有线程都运行结束,才会结束。有一种特殊的线程叫做守护线程,只要其它非守护线程运行结束了,即使守护线程的代码没有执行完,也会强制结束。

@Slf4j(topic = "c.Test1")
public class Test1 {
    public static void main(String[] args) throws InterruptedException {
        log.debug("开始运行...");
        Thread t1 = new Thread(() -> {
            log.debug("开始运行...");
            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.debug("运行结束...");
        }, "daemon");
        // 设置该线程为守护线程
        t1.setDaemon(true);
        t1.start();
        Thread.sleep(1);
        log.debug("运行结束...");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值