JavaEE——Thread类的基本用法

目录

一、Java多种方法创建线程

二、Thread类及常见方法

三、线程的状态

 

1.继承Thread类,继承 Thread 来创建一个线程类

 创建 MyThread 类的实例

调用 start方法启动线程

整体代码:

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("这是线程要运行的代码");

    }
}
public class Demo6 {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();//线程开始运行
    }
}

 

1.2实现Runnable 接口,创建线程

 创建 Thread 类实例,调用 Thread 的构造方法时将 Runnable对象作为 target 参数.

调用start方法

整体代码:

class MyThread implements Runnable {
    @Override
    public void run() {
        System.out.println("这是线程要运行的代码");
    }
}
public class Demo6 {
    public static void main(String[] args) {
        Thread t = new Thread(new MyThread());
        t.start();//线程开始运行
    }
}



 

1.3注意,对比上面两种方法:
*继承 Thread 类,直接使用 this 就表示当前线程对象的引用.
*实现 Runnable 接口,this 表示的是 MyThread 的引用.需要使用
Thread.currentThread() 

1.4匿名内部类创建 Thread 子类对象 

 

 

 1.5匿名内部类创建 Runnable 子类对象

 

1.6匿名内部类创建:完整代码  

public class Demo4 {

    public static void main(String[] args) {
        Thread T1 = new Thread() {
            public void run(){
                System.out.println("");
            }
        };
    }
      Thread T2 =new Thread(new Runnable() {
          @Override
          public void run() {
              System.out.println("使用匿名类创建Runnable子类对象");
          }
      });
}
 

 

1.6 lambda 表达式创建 Runnable 子类对象 

 

2 Thread类及常见方法

Thread 类是 JVM 用来管理线程的一个类,换句话说,每个线程都有一个唯一的 Thread 对象与之关联。 而 Thread 类的对象就是用来描述一个线程执行流的,JVM 会将这些 Thread 对象组织起来,用于线程调度,线程管理。

 

 

2.1 Thread 的常见构造方法

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

 

  2.2 Thread 的几个常见属性

1.ID 是线程的唯一标识,不同线程不会重复
2.名称是各种调试工具用到
3.状态表示线程当前所处的一个情况,下面我们会进一步说明
4.优先级高的线程理论上来说更容易被调度到
5.关于后台线程,需要记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行
6.是否存活,即简单的理解,为 run方法是否运行结束了
7.线程的中断问题,下面我们进一步说明 

 

2.3 启动一个线程-start()

之前我们已经看到了如何通过覆写 run 方法创建一个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。
(1)覆写 run 方法是提供给线程要做的事情的指令清单
(2)而调用 start() 方法,就是喊一声:”行动起来!“,线程才真正独立去执行了

调用 start 方法,才真的在操作系统的底层创建出一个线程。

 

2.4 中断一个线程

线程一旦进到工作状态,他就会按照覆写run方法步骤去进行工作,不完成是不会结束的。

那么我们怎么中途让线程停止呢?

目前常见的有以下两种方式:
(1)通过共享的标记来进行沟通
(2)调用 interrupt()方法来通知


示例-1:使用自定义的变量来作为标志位。需要给标志位上加 volatile 关键字(这个关键字的功能后面介绍)

示例-2:使用 Thread.interrupted()或者Thread.currentThread().isInterrupted()代替自定义标志位
Thread 内部包含了一个 boolean 类型的变量作为线程是否被中断的标记

使用 thread 对象的 interrupted()方法通知线程结束

抛出异常

 

是由于 判定 isInterrupted()和 执行打印,这俩操作,太快了因此整个循环,主要的时间都是花在,sleep 1000 上,main 调用 Interrupt 的时候, 大概率,t线程正处于 sleep 状态中呢,此处 Interrupt 不仅仅能设置标志位,还能把刚才这个 sleep 操作,给唤醒。
比如, sleep 此时刚睡了 100ms, 还剩 900ms, 此时 Interrupt 被调用了
此时 sleep 就会直接被唤醒, 并且抛出 InterruptedException 异常~~

但是,循环还是在继续执行.看起来就好像这个标志位,没有被设置一样~~

但是注意这里的设定!!!
首先, Interrupt 肯定会设置这个标志位的!!!
其次,当 sleep 等阻塞的函数被唤醒之后,就会先清空刚才设置的 interrupted 标志位

这是JVM 内部的逻辑,需要结合 JVM 的源码才能看到这个操作! (我们记住结论就好)

那我们如何让线程停止呢?

 我们修改catch中的默认内容,由于 catch 中默认代码再次抛出异常,再次抛出的异常
没人 catch, 最终就到了 JVM 这一层,进程就直接异常终止 

结论:
1.Interrupt 方法能够设置标志位, 也能唤醒 sleep 等阻塞方法
2. sleep 被唤醒之后, 又能清空标志位, 

 

2.5 等待一个线程-join()


有时,我们需要等待一个线程完成它的工作后,才能进行自己的下一步工作。

 

大家可以试试如果把两个join 注释掉,现象会是怎么样的呢?
附录 

方法说明
public void join()等待线程结束
public void join(long millis)等待线程结束,最多等 millis 毫秒
public void join(long millis, int nanos)同理,但可以更高精度

 

2.6 获取当前线程引用
这个方法我们已经非常熟悉了(有点像this) 

方法说明
public static Thread currentThread();返回当前的对象引用

 

 

2.7 休眠当前线程
也是我们比较熟悉一组方法,有一点要记得,因为线程的调度是不可控的,所以,这个方法只能保证实际休眠时间是大于等于参数设置的休眠时间的。

方法说明
public static void sleep(long millis) throws InterruptedException休眠当前线程
public static void sleep(long millis,int nanos) throws InterruptedException可以更高精度的休眠

3.线程的状态


3.1 观察线程的所有状态
线程的状态是一个枚举类型 Thread.State

NEW:安排了工作,还未开始行动(当前 Thread 对象虽然有了,但是内核的线程还没有 (还没调用过 start))
RUNNABLE:可工作的,又可以分成正在工作中和即将开始工作(就绪状态.正在 cpu 上运行 + 随时可以去 cpu 上运行)
BLOCKED: 这几个都表示排队等着其他事情(因为 锁 竞争,引起的阻塞.)
WAITING:这几个都表示排队等着其他事情(没有超时时间的阻塞等待
join / wait,"死等")

TIMED_WAITING:这几个都表示排队等着其他事情(有超时时间的等待
比如 sleep, 或者 join 带参数版本.....)

TERMINATED:工作完成了(当前 Thread 对象虽然还在,但是内核的线程已经销毁(线程已经结束了))

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值