【JavaEE】Thread 类的基本用法

目录

1. 线程创建

2. 线程中断

3. 线程等待

4. 线程休眠

5. 获取线程实例


Thread类是我们在线程学习过程中常见的使用,我们要想熟悉运用可以从一下几个方面来学习,线程创建、线程中断、线程等待、线程休眠、获取线程实例。

1. 线程创建

线程的创建我们,可以通过

  1. 继承 Thread, 重写 run
  2. 实现 Runnable, 重写 run
  3. 继承 Thread, 重写 run, 使用匿名内部类
  4. 实现 Runnable, 重写 run, 使用匿名内部类
  5. 使用 lambda 表达式

这五种方式来实现。

 1.1 继承Thread

public class 继承Thread {
    public static void main(String[] args) {
        // 继承的方法一:
        // 创建一个线程
        myThread myThread = new myThread();
        myThread.start();

        // 继承的方法二:
        // 使用一个匿名内部类
        Thread t = new Thread() {
            @Override
            public void run() {
                System.out.println("匿名内部类 run");
            }
        };
    }

    // 继承的方式,1.继承Thread。2.重写run方法
    private static class myThread extends Thread {
        @Override
        public void run() {
            System.out.println("MyThread run");
        }
    }
}

 1.2 实现Runnable

public class 实现Runnable {
    public static void main(String[] args) {

        Thread t = new Thread(new MyRunnable());
        t.start();

        Runnable r = new Runnable() {// 属于runnable接口实现类,只是没有名字
            @Override
            public void run() {
                System.out.println("匿名内部类 run");
            }
        };

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {

            }
        });
        t2.start();
    }

    private static class MyRunnable implements Runnable{
        @Override
        public void run() {
            System.out.println("MyRunnable run");
        }
    }
}

 1.3 使用lambda表达式

        Thread t3 = new Thread(() -> System.out.println("匿名内部类 run"));
        t3.start();

2. 线程中断

上面创建的线程,启动它的命令就是我们看到的.start();命令,但是这个命令一但启动,那就必须执行完才可以结束,但是实际运用中我们不可能只进行这一个线程,如果想要进行其他的线程,我们就要接触到这一节的内容。

目前常见的有以下两种方式:

  1. 通过共享的标记来进行
  2. 调用 interrupt() 方法

2.1 自定义标记位

public class 自定义标记为 {
    
    //先设计一个标志位:表示是否被中断。这里volatile后续学习
    private static volatile boolean 是否被中断 = false;

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                //循环10次,每次打印次数,并休眠1秒
                try {
                    //判断条件加上标志位
                    for (int i = 0; i < 10 && !是否被中断; i++) {
                        System.out.println(i);
                        //自定义标志位,能够实现某些条件的中断
                        //但如果线程处于等待/超时等待/阻塞, 就没法中断
                        //修改时间为100秒就没法中断
                        Thread.sleep(1000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
        //要中断t线程:等3后再中断
        Thread.sleep(3000);
        是否被中断 = true;
    }

}

2.2 调用 interrupt() 方法

我们先来认识一下interrupt()方法:

方法 说明
public void interrupt() 中断对象关联的线程,如果线程正在阻塞,则以异常方式通知,
否则设置标志位
public static boolean
interrupted()
判断当前线程的中断标志位是否设置,调用后清除标志位
public boolean
isInterrupted()
判断对象关联的线程的标志位是否设置,调用后不清除标志位
public class ThreadDemo {
    private static class MyRunnable implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.interrupted());
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        MyRunnable target = new MyRunnable();
        Thread thread = new Thread(target, "李四");
        thread.start();
        thread.interrupt();
    }
}z

//结果
true // 只有一开始是 true,后边都是 false,因为标志位被清
false
false
false
false
false
false
false
false
false

--使用 Thread.currentThread().isInterrupted() , 线程中断标记位不会清除
 

public class ThreadDemo {
    private static class MyRunnable implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().isInterrupted());
            }
           
        }
    }
    public static void main(String[] args) throws InterruptedException {
        MyRunnable target = new MyRunnable();
        Thread thread = new Thread(target, "李四");
        thread.start();
        thread.interrupt();
    }
}

// 结果
true // 全部是 true,因为标志位没有被清
true
true
true
true
true
true
true
true
true

3. 线程等待

线程的等待就是在执行一个线程的时候,等待一个线程完成它的工作后,才能进行自己的下一步工作。

这是我们就要使用join()方法;

方法 说明
public void join() 等待线程结束
public void join(long millis) 等待线程结束,最多等 millis 毫秒
public void join(long millis, int nanos) 同理,但可以更高精度
public class Demo {
    
    public static void main(String[] args) throws InterruptedException {
        Runnable target = () -> {
            for (int i = 0; i < 10; i++) {
                try {
                    System.out.println(Thread.currentThread().getName()
                            + ": 我还在工作!");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + ": 我结束了!");
        };
        Thread thread1 = new Thread(target, "李四");
        Thread thread2 = new Thread(target, "王五");
        System.out.println("先让李四开始工作");
        thread1.start();
        thread1.join();
        System.out.println("李四工作结束了,让王五开始工作");
        thread2.start();
        thread2.join();
        System.out.println("王五工作结束了");
    }
}

4. 线程休眠

方法 说明
public static void sleep(long millis) throws InterruptedException 休眠当前线程 millis 毫
public static void sleep(long millis, int nanos) throws
InterruptedException
可以更高精度的休眠
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        System.out.println(System.currentTimeMillis());
        Thread.sleep(3 * 1000);
        System.out.println(System.currentTimeMillis());
    }
}

注意休眠和等待的区别;

5. 获取线程实例

这个经过前面的学习我们应该已经很熟悉了。

方法 说明
public static Thread currentThread(); 返回当前线程对象的引用
public class Demo {
    public static void main(String[] args) {
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName());
    }
}

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