Thread相关的重要方法,interrupted与sleep同时使用

本文详细介绍了Java多线程中的关键方法,如Thread.sleep()、getId()、getName()等,讨论了后台线程(isDaemon)、线程状态(isAlive)、启动线程(start)、Thread.currentThread()、isInterrupted()的使用,以及如何正确处理线程中断和同步(synchronized)。

目录

1.Thread.sleep(); 

2. t1.getId();

3.t1.getName();

4.isDaemon 

5.isAlive(); 

6.t1.start(); 

7,8,9代码示例

7.Thread.currentThread();

8.isInterrupted();   

9.t1.join();

10.synchronized关键字


1.Thread.sleep(); 

方法括号中输入时间,单位ms,让此线程休眠多长时间.

2. t1.getId();

Thread创建实例,假设创建出的线程为t1  (不知道如何用Thread创建线程的可以参考我上一篇博文),此时     t1.getId();可以得到此线程的编号,这个编号是编译器赋予的,具有唯一性

3.t1.getName();

是可以获取线程的名字的,和Id不一样,它可以是我们程序员参与,如果不干预编译器默认会从线程1 , 2 , 3, 4........排序,可以在我们的jdk中的jconsole中查看不同线程以及他们的名字,同理,我们可以用代码编译 new Thread(String name);  或者  new Thread(Runnable Target,String name);

4.isDaemon 

判断是否为后台线程(手动线程),与之相对应的还有前台线程.

后台线程: 进程结束后后台线程不管是否执行完毕都结束.

前台线程: 前台线程会结束之后进程才能结束.

t1.setDeamon( false); 将此线程设定为前台线程.

t1.setDeamon(true); 将此线程设定为后台线程.

5.isAlive(); 

表示了,内核中的线程(PCB)是否还存在,

java代码中定义的线程对象(Thread)实例,虽然表示一个线程,但是这个对象本身的生命周期和内核中的pcb生命周期时不同的.

Thread t1 = new Thread(runnable);  此时虽然创建出了t1,但是t1.isAlive();  是false因为此时还没有创建线程,.

t1.start();之后t1.isAlive(); 输出true.

当run()方法执行完毕,t1.isAlive();输出false;

6.t1.start()

启动线程,但是每个线程只能启动一次.

7,8,9代码示例

public class ThreadDemo7 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while(!Thread.currentThread().isInterrupted()){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("正在工作中");
            }
            System.out.println("工作结束");
        });
        t1.start();
        Thread.sleep(3000);
        System.out.println("让t1线程结束");
        t1.interrupt();
    }
}

7.Thread.currentThread();

代码中代指t1,相当于this,多线程中用这个方法.

8.isInterrupted();   

标志位 , 当前线程是否被打断 , 没有打断返回false , 此时一直进行while循环

t1.interrupt();

打断.此时isInterrupted();标志位 返回true.此时循环结束,进程结束.

9.t1.join();

让当前线程(主线程)等待t1线程结束后结束,括号中可以写上时间(ms),如果到达时间t1还没有执行完main就会往下执行.

但是观察代码结果发现并没有按照预期结束,

此异常由interrupt()引起,Interrupt()让sleep的睡眠时间变为不确定因素,如果线程t1睡眠时调用Interrupt方法会使sleep提前唤醒,此时sleep抛出异常,同时清除interrupted()的标志位变回false,

此时循环继续,打断线程执行失败.

解决方案就是在sleep抛出异常的时候不进行下一次循环直接break,这样就不会清除isInterrupted的状态栏了.

public class ThreadDemo7 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while(!Thread.currentThread().isInterrupted()){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
                System.out.println("正在工作中");
            }
            System.out.println("工作结束");
        });
        t1.start();
        Thread.sleep(3000);
        System.out.println("让t1线程结束");
        t1.interrupt();
    }
}

此时抛出异常,线程执行完毕.

10.synchronized关键字

对一个线程中的步骤进行加锁,锁内的步骤进行是其他加同样锁的线程阻塞不能进行

例如:上厕所每个隔间都有一把锁,一个线程拿到这把锁,其他线程就必须等带此线程执行完毕,其他线程再去竞争锁,得到锁后此线程执行,其他持有相同锁的线程等待(阻塞)

产生阻塞的情况也称为锁冲突,锁竞争.

如果对于不同的对象进行上锁,此时就不会产生冲突.

随便创建个对象就可以用来加锁,但是一定要记住对同一对象上锁,不然不会阻塞!!!!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值