JavaThread 类的基本用法

  • 1.线程创建
  • 2.线程中断
  • 3.线程等待
  • 4.获取线程实例
  • 5.线程休眠

1.线程创建

Thread常见的构造方法

方法 说明
Thread() 创建线程对象
Thread(Runnable target) 使用 Runnable 对象创建线程对象
Thread(String name) 创建线程对象,并命名
Thread(Runnable target, String name) 使用 Runnable 对象创建线程对象,并命名
【了解】Thread(ThreadGroup group,Runnable target) 线程可以被用来分组管理,分好的组即为线程组,这
  1. 继承Thread类,重写run方法

先创建一个类,然后继承Thread这个父类,在重写run方法

class MyThread extends Thread{
    @Override
    public void run() {
        while(true){
            System.out.println("继承Thread类,重写run");
        }
    }
}
public class ThreadDemo1 {
    public static void main(String[] args) {
        //继承Thread父类,这里new的是自己写的一个类
        Thread t = new MyThread();
        t.start();
    }
}

  1. 实现Runnable接口
class MyRunnable implements Runnable{

    @Override
    public void run() {
        System.out.println("继承Runnable接口");
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        //创建任务
        Runnable runnable = new MyRunnable();
        //把任务交给线程执行
        Thread t = new Thread(runnable);
        t.start();
    }
}
  1. 使用匿名内部类,继承Thread类
public class ThreadDemo3 {
    public static void main(String[] args) {
  		//1.创建了一个Thread子类(匿名)
        //2.创建了子类的实例,并且让t引用执行该实例
        Thread t = new Thread(){
            @Override
            public void run() {
                System.out.println("使用匿名匿名内部类,继承Thread");
            }
        };
        //线程开始
        t.start();
    }
}
  1. 使用匿名内部类,实现Runnable
public class ThreadDemo4 {
    public static void main(String[] args) {
        //创建了一个类,实现了Runnable 同时创建了类的实例
        //并且传给了Thread的构造方法
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("使用匿名内部类,实现Runnable");
            }
        },"myThread");//给该线程取的名字
        t.start();
    }
}
  1. 使用Lambda表达式(最常用的方法)
public class ThreadDemo5 {
    public static void main(String[] args) {
        //把任务用lambda表达式描述然后直接把lambda传给Thread构造方法
        Thread t = new Thread(()->{
            System.out.println("使用lambda表达式");
        });
        t.start();
    }
}

2.线程中断

线程中断:并不是让线程停止就立马停止,而是通知线程应该停止了,是否真正的停止,取决于线程这里的具体代码写法.

  1. 使用自定 标志位来控制线程是否要停止
public class ThreadDemo8 {
    //	"自定义标志符"
    private static boolean flag = true;

    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while(flag){
                System.out.println("hello");
            }
        });
        t.start();
        //在主线程里可以随意操作flag变量值,来控制t线程是否结束
        //flag = false;
    }
}

  1. 使用 interrupt() 终止线程

interrupt()是Thread自带的标志位.这个东西可以唤醒sleep方法.

方法 说明
public void interrupt() 中断对象关联的线程,如果线程正在阻塞,则以异常方式通知,否则设置标志位
public static boolean interrupted() 判断当前线程的中断标志位是否设置,调用后清除标志位
public boolean isInterrupted() 判断对象关联的线程的标志位是否设置,调用后不清除标志位
public class ThreadDemo9 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while(! Thread.currentThread().isInterrupted()){
                System.out.println("hello");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                    break;//注释1处
                }
            }
        });
        t.start();
        //终止线程
        t.interrupt();
    }
}
  • currentThread():是Thread静态方法,通过这个方法获取当前线程,哪个线程调用这个方法,就获取哪个线程的对象引用.(上述代码就是获取的t线程).
  • isInterrupted():为true表示被终止,false表示没有终止.
  • interrupt():哪个线程调用就终止哪个线程,也就是把isInterrupted()这个标志位设置为true.
  • 如果该线程调用interrupt()时,在sleep中,可以直接被唤醒,从sleep中提前返回/唤醒了,也就是可以触发sleep中一个异常,导致sleep提前醒来,但是当sleep被唤醒的时候,会把isInterrupted()重新设置成false(清空了标志位).
  • 注释1处:加个break表示,即使把sleep唤醒之后把isInterrupted()重新设置成false(清空了标志位).,依旧会直接把线程终止.(因为sleep被触发异常后会被捕获然后执行到break)

3.线程等待

线程是一个随机调度的过程,所有完全无法判断线程之间的执行顺序,所以为了能判断线程的执行顺序就有了等待线程,控制线程的结束顺序.

  1. 等待一个线程 join()
public class ThreadDemo10 {
    public static void main(String[] args) {
        //创建一个线程
        Thread t = new Thread(()->{
            for (int i = 0; i < 100; i++) {
                System.out.println("想你的第"+i+"天");
            }
        });
        //线程开始
        t.start();
        
        try {
            t.join();//注释1处
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

  • 注释1处: 表示让main这个线程等待t线程结束,才继续往下执行.
  • join()在哪个线程里就是哪个线程等待.在mian里调用t.join(),就是让mian等待t结束,此时main会进入阻塞等待的状态.
  • join()并不是一定会等待,如果在执行join()的时候,t已经结束了,就不会让main等待.
方法 说明
public void join() 等待线程结束
public void join(long millis) 等待线程结束,最多等 millis 毫秒
public void join(long millis, int nanos) 同理,但可以更高精度
  • join() :无参数版本,“无终止的等”

  • join(long millis): 指定一个超时的时间,时间到了就不再等待

4.获取线程实例

方法 说明
public static Thread currentThread(); 返回当前线程对象的引用
public class ThreadDemo11 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            System.out.println("哈喽啊");
        });
        //1.直接用类名来调用 返回t这个对象引用
        Thread.currentThread();

        //2.第二种方法 返回t2这个对象引用
        Thread t2 = Thread.currentThread();
        t2.getName();
    }
}

5.线程休眠

线程休眠就是休眠线程,本质上是不让这个线程参与调度(不去CPU跑了);

方法 说明
public static void sleep(long millis) throws InterruptedException 休眠当前线程 millis毫秒
public static void sleep(long millis, int nanos) throws InterruptedException 可以更高精度的休眠
public class ThreadDemo12 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            System.out.println("等待1000ms");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        t.start();
    }
}
  • sleep()是通过Thread类直接调用的,在t线程里调用就是让t进行休眠,进入阻塞队列.
  • 当t线程sleep时间结束时,回到就绪队列,考虑到线程之间调度的问题,对应的线程是无法在唤醒之后立马被执行,所以意味着实际休眠时间大概率要大于1000ms.

你可能感兴趣的:(JavaEE,开发语言,Thread,JavaEE)