Java - Thread类

目录

目录

一.Java的线程模型

​编辑

二.创建线程的五种方法

1.继承Thread类

2.实现Runnable接口

3.匿名内部类创建Thread子类

4.匿名内部类创建Runnable子类

5.Lambad创建Runnable子类

三.线程中断

1.public void interrupt()

2.public static boolean interrupted()

3.public boolean isInterrupted()

四、等待线程


一.Java的线程模型

        所谓线程模型就是虚拟CPU、执行代码和操作数据三者的封装体。在java中,线程模型通过java.lang包中的Thread类描述和声明。当然,除了Thread类可以支持线程外,还有Runnable接口,Object类,ThreadGroup类,ThreadDeath类。

这五者的关系如👇图:


二.创建线程的五种方法

1.继承Thread类

覆盖run()方法。

class myThread extends Thread{
    @Override
    public void run() {
        System.out.println("继承Thread创建线程");
    }
}

2.实现Runnable接口

1.将一个类实现Runnable接口

class myThread implements Runnable{
    @Override
    public void run() {
        System.out.println("继承Runnable创建线程");
    }
}

2.创建线程对象

使用Thread类的构造方法,即      Thread 对象名 = new Thread(实现Runnable接口类的对象);

后对象名.start()启动线程。


3.匿名内部类创建Thread子类

public static void main(String[] args) {
        Thread t = new Thread(){
            public void run(){
                System.out.println("匿名内部类创建Thread子类,重写run方法");
            }
        };
        t.start();
    }

4.匿名内部类创建Runnable子类

public static void main(String[] args) {
        Thread t = new Thread(new Runnable()
        {
            public void run(){
                System.out.println("匿名内部类创建Runnable子类,重写run方法");
            }
        });
        t.start();
    }

5.Lambad创建Runnable子类

public static void main(String[] args) {
        Thread t = new Thread(()-> System.out.println("Lambda表达式创建Runnable子类"));
        t.start();
    }

三.线程中断

        中断线程不是让线程直接停下来,而是通知线程结束,而线程具体的执行,取决于线程自身的代码。Thread类关于中断有三个实例方法,interrupt(),interrupted(),isinterrupted()。

1.public void interrupt()

        当调用这个方法时,调用这个方法的线程对象会通知目标线程中断,并将目标线程的中断标志位设置为true。如果线程处于wait(),join(),sleep()阻塞状态,则会抛出异常。

2.public static boolean interrupted()

        用于判断目标线程是否设置中断标志位,调用后会清除标志位。

使用interrupted()来中断一个线程:

public static void main(String[] args) {
        Thread t = new Thread(){
            public void run(){
                while (true){
                    if(Thread.interrupted()){
                        System.out.println(Thread.currentThread().getName()+"  "+"has interrupting");
                         break;
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break;
                    }
                    System.out.println("hello");
                }
            }
        };
        t.start();
        try {
            Thread.sleep(10*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.interrupt();
    }

3.public boolean isInterrupted()

        用于判断目标线程是否设置中断标志位,调用后不会清除标志位。

使用isInterrupted()来中断一个线程:

public static void main(String[] args) {
        Thread t = new Thread(){
            public void run(){ 
                while (!Thread.currentThread().isInterrupted()){
                    System.out.println("hello");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break;
                    }
                }
            }
        };
        t.start();
        try {
            Thread.sleep(10*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.interrupt();
    }

两种运行结果相同:10秒内,每隔1秒打印1个hello,然后抛出异常后,结束线程。

以上这两种中断方法的可行性,都取决于sleep处理异常的代码,由于break的存在,线程才能顺利中断,所以catch代码的写法,决定了中断的结果,可以选择不中断,也可以选择过会中断,也可以立即中断,这一切都取决于编写代码的程序员本身。


四、等待线程

Thread类给了我们join()方法来让其他线程阻塞等待目标线程结束再运行。

当然Thread还给了我们join(long millis),join(long millis,int nanos)两个方法限定等待的最长时间,

而我们的join()方法是死等,如果在调用join之前,目标线程已经结束了,就不会阻塞等待。

等待线程实现代码:

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            public void run(){
                int i = 0;
                while(i<3){
                    System.out.println("t running");
                    try {
                        sleep(1000);
                        i++;
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("t end");
            }
        };
        System.out.println("main start");
        t.start();
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Thread.sleep(2000);
        System.out.println("main end");
        System.out.println("over");
    }

如果是没有加join()的运行结果:

main start
t running
t running
main end
over
t running
t end

很明显main线程并没有等待t线程,而是二者一块运行。

运行结果:

main start
t running
t running
t running
t end
main end
over

 可见,main线程是等待了t线程执行完后,再继续执行。

以上就是本文的全部内容了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

todd1er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值