JAVAEE初阶相关内容第三弹--多线程(初阶)

本文详细介绍了Java中的Thread类,包括其构造方法、常见属性(如daemon状态、isAlive和中断机制)、抢占式执行以及join方法的使用。重点讨论了后台线程、线程状态检查和如何控制线程的执行流程。
摘要由CSDN通过智能技术生成

目录

Thread类及常见方法

1.Thread的常见构造方法

2.Thread的几个常见属性

(1)setDaemon()

(2)isAlive()

3.抢占式执行

4.中断一个线程

终止分为以下三种:

(1)忽略了请求,继续执行

(2)线程t立即响应请求

(3)稍后进行终止

5.等待一个线程join()


Thread类及常见方法

Thread类是JVM用来管理线程的一个类,换句话说,每个线程都有唯一的Thread对象与之关联。

1.Thread的常见构造方法

方法说明
Thread创建线程对象
Thread(Runnable target)使用Runnable对象创建线程对象
Thread(String name)创建线程对象,并命名
Thread(Runnable target,String name)使用Runnable对象创建线程对象并命名
Thread(ThreadGroup group,Runnable target)线程可以被用来分组管理,分好的组即为线程组,这个目前了解即可。

这里第二和第三行的参数多了name,目的是为了方便测试。

public class ThreadD6 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    System.out.println("ThreadD6");
                }
            }
        },"D6");
        t.start();
    }
}

2.Thread的几个常见属性

属性获取方法备注
IDgetId()
名称getName()构造方法里起的名字
状态getState()线程状态(Java里面的线程状态比操作系统原生状态更丰富)
优先级getPriority()可获取,可设置,但是没有用
是否是后台线程(守护线程)isDaemon()

(1)前台线程会阻止进程结束,前台线程的工作没做完,进程是完成不了的,后台线程不会阻止线程的结束。

(2)代码中手动创建的线程一般都是前台线程,包括在main()函数也默认是前台的,其他的jvm自带的线程都是后台的。

(3)也可以使用setDaemon()来设置后台线程。

是否存活isAlive()

(1)判断当前系统里的这个线程是不是真的有了。如果内核里的线程把run跑完了,此时线程销毁,pcb随之释放,但是Thread t 这个对象不一定被释放,此时的isAlive也是false。

(2)t.start:让内核创建一个pcb,此时pcb表示一个真正的线程。

(3)在真正调用start之前,调用t.Alive()就是false。调用strat之后,isAlive就是true.

是否被中断(终止)isInterrupted()

不是让线程立即终止,而是通知线程应该要停止了,是否真的停止取决于线程这里具体的写法,

(1)使用标志位来控制线程是否要停止。(自定义变量这种方式不能及时响应,尤其是在sleep进行休眠的时候)

(2)使用Thread自带的标志位进行预判。(唤醒上面sleep这样的方法)

(1)setDaemon()

代码:

public class ThreadD6 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
               while(true){
                   System.out.println("helloD6");
               }
            }
        },"D6");
        t.setDaemon(true);
        t.start();
    }
}

结果:

 不设置成后台线程的输出结果:

 把t设置成守护线程/后台线程,此时进程的结束与否就和t无关了。

(2)isAlive()

(1)内核里的线程把run跑完了,此时线程销毁,pcb随之释放,但是Thread t 这个对象不一定被释放,此时的isAlive也是false。

public class ThreadD6 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                   System.out.println("hello");
            }
        },"D6");

        t.start();
        while(true){
            try {
                Thread.sleep(1000);
                System.out.println(t.isAlive());
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

结果:

使用一个for循环, 使run()先休眠三秒再继续往下执行,这里的isAlive()首先打印出来的就是false;

public class ThreadD6 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    System.out.println("D6");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        },"D6");

        t.start();
        while(true){
            try {
                Thread.sleep(1000);
                System.out.println(t.isAlive());
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

执行结果:

 如果t的run还没跑,isLive就是false

 如果t的run正在跑,isLive就是true

 如果t的run跑完了,isLive就是false

3.抢占式执行

在进程执行的过程中,哪一部分先执行,哪一部分后执行是随机的。

例如:

public class ThreadD7 {
    public static void main(String[] args) {
        Thread t = new Thread(() ->{
            System.out.println("D7");
        });
        t.start();
        System.out.println("mainD7");
    }
}

在上面的代码中,主函数有一个线程,还有一个调用的线程,这里的

 这两部分的代码谁先执行谁后执行是不能被确定的,是随机的执行。

4.中断一个线程

不是让线程立即终止,而是通知线程应该要停止了,是否真的停止取决于线程这里具体的写法.

(1)使用标志位来控制线程是否要停止。(自定义变量这种方式不能及时响应,尤其是在sleep进行休眠的时候)

public class ThreadD8 {
    private static boolean flag = true;
    public static void main(String[] args) {
        Thread t = new Thread(() ->{
           while (flag){
               System.out.println("D8");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        });
        t.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        flag = false;
    }
}

结果:

(2)使用Thread自带的标志位进行预判。(唤醒上面sleep这样的方法)

public class ThreadD9 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() ->{
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("D9");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
        Thread.sleep(1000);
        t.interrupt();
    }
}

结果:

interrupt会做两件事:

(1)把线程内部的标志位(boolean)给设置成true

(2)如果线程在进行sleep,就会触发异常,就会把sleep唤醒

但是!!在sleep在唤醒的时候,还会做一件事,把刚才设置的这个标志位,再设置成false(清空了标志位)。

需要注意的是,调用interrupt,只是通知终止,不是线程一定要乖乖终止。

终止分为以下三种:

(1)忽略了请求,继续执行

运行结果:

 完整代码:

public class ThreadD9_1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() ->{
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("D9");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        });
        t.start();
        Thread.sleep(3000);
        t.interrupt();
    }
}
(2)线程t立即响应请求

 运行结果:

 完整代码:

public class ThreadD9_2 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() ->{
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("D9");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
            }

        });
        t.start();
        Thread.sleep(3000);
        t.interrupt();
    }
}
(3)稍后进行终止

 结果;

 完整代码:

public class ThreadD9_3 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() ->{
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("D9");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                    break;
                }
            }

        });
        t.start();
        Thread.sleep(3000);
        t.interrupt();
    }
}

5.等待一个线程join()

等待一个线程结束。等待线程:控制执行顺序。
有时我们需要等待一个线程完成他的工作后,才能进行自己的下一步工作。

关于join()
方法说明解释
public void join()等待线程结束”死等“,无参数版
public void join (long millis)

等待线程结束,最多等待millis毫秒

指定一个超时时间(最大等待时间)
piblic void join(long millis,int nanos)同理,但是可更高精度

代码:

public class ThreadD10 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 3; i++) {
                System.out.println("D10");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();

        System.out.println("join之前");
        try {
            t.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("join之后");
    }
}

结果:

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

西西¥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值