详解Thread类及线程中的几种状态

前言

本篇博客将从以下几个方面详解Thread类及Java中线程的几种状态

一.Thread类

1.1创建线程

方法一 继承Thread类

class MyThread extends Thread {
 @Override
 public void run() {
 System.out.println("这⾥是线程运⾏的代码");
 }
}
MyThread t = new MyThread();
t.start();

方法二 实现runnable 接口

class MyRunnable implements Runnable {
 @Override
 public void run() {
 System.out.println("这⾥是线程运⾏的代码");
 }
}
Thread t = new Thread(new MyRunnable());
t.start();

方法三 使用匿名内部类创建Thread子类对象

// 使⽤匿名类创建 Thread ⼦类对象
Thread t1 = new Thread() {
 @Override
 public void run() {
 System.out.println("使⽤匿名类创建 Thread ⼦类对象");
 }
};

方法四 使用匿名内部类创建Runnable子类对象

// 使⽤匿名类创建 Runnable ⼦类对象
Thread t2 = new Thread(new Runnable() {
 @Override
 public void run() {
 System.out.println("使⽤匿名类创建 Runnable ⼦类对象");
 }
});

方法五 使用lambda表达式创建Runnable 子类对象

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

        while (true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

1.2中断线程

例:

李四⼀旦进到⼯作状态,他就会按照⾏动指南上的步骤去进⾏⼯作,不完成是不会结束的。但有时我 们需要增加⼀些机制,例如⽼板突然来电话了,说转账的对⽅是个骗⼦,需要赶紧停⽌转账,那张三该如何通知李四停⽌呢?这就涉及到我们的停⽌线程的⽅式了。
目前常见的有以下两种方式:
1.通过共享的标记来进行沟通
2.调用interrupt()方法来通知
示例1 使用自定义的变量来作为标志位
public class ThreadDemo {
 private static class MyRunnable implements Runnable {
 public volatile boolean isQuit = false;
 @Override
 public void run() {
 while (!isQuit) {
 System.out.println(Thread.currentThread().getName()
 + ": 别管我,我忙着转账呢!");
 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 System.out.println(Thread.currentThread().getName()
 + ": 啊!险些误了⼤事");
 }
 }
 public static void main(String[] args) throws InterruptedException {
 MyRunnable target = new MyRunnable();
 Thread thread = new Thread(target, "李四");
 System.out.println(Thread.currentThread().getName()
 + ": 让李四开始转账。");
 thread.start();
 Thread.sleep(10 * 1000);
 System.out.println(Thread.currentThread().getName()
 + ": ⽼板来电话了,得赶紧通知李四对⽅是个骗⼦!");
 target.isQuit = true;
 }
}

示例二 使用Thread.interrupted()或者Thread.currentThread().isInterrupted()代替自定义标志位

注:Thread 内部包含了⼀个 boolean 类型的变量作为线程是否被中断的标记.

public class ThreadDemo {
private static class MyRunnable implements Runnable {
() {
@Override
 public void run
 // 两种⽅法均可以
 while (!Thread.interrupted()) {
 //while (!Thread.currentThread().isInterrupted()) {
 System.out.println(Thread.currentThread().getName()
 + ": 别管我,我忙着转账呢!");
 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 System.out.println(Thread.currentThread().getName()
 + ": 有内⻤,终⽌交易!");
 // 注意此处的 break
 break;
 }
 }
 System.out.println(Thread.currentThread().getName()
 + ": 啊!险些误了⼤事");
 }
 }
 public static void main(String[] args) throws InterruptedException {
 MyRunnable target = new MyRunnable();
 Thread thread = new Thread(target, "李四");
 System.out.println(Thread.currentThread().getName()
 + ": 让李四开始转账。");
 thread.start();
 Thread.sleep(10 * 1000);
 System.out.println(Thread.currentThread().getName()
 + ": ⽼板来电话了,得赶紧通知李四对⽅是个骗⼦!");
 thread.interrupt();
 }
}

1.3等待线程

有时,我们需要等待⼀个线程完成它的⼯作后,才能进⾏⾃⼰的下⼀步⼯作。例如,张三只有等李四 转账成功,才决定是否存钱,这时我们需要⼀个⽅法明确等待线程的结束。

我们一般用join()这个方法

public class ThreadDemo {
 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("王五⼯作结束了");
 }
 }

注:run()方法和start()方法的区别

1.run()方法是线程执行的代码块,只有在start()方法被调用后才会执行。如果直接调用run()方法,实际上就是普通的方法调用,不会开启新的线程,而是在当前线程中运行这个方法;

2.start()方法是开启线程的方法,它会创建一个新的线程,并在新的线程中调用run()方法;

3.在多线程编程中,如果直接调用run()方法,那么所有的操作都是在主线程中完成的,而不是在新的线程中执行,这就不符合多线程编程的目的,因此,应该调用start()方法来开启新的线程,以实现多线程编程的目的。

1.4休眠线程

代码如下:

public class ThreadDemo {
 public static void main(String[] args) throws InterruptedException {
 System.out.println(System.currentTimeMillis());
 Thread.sleep(3 * 1000);
 System.out.println(System.currentTimeMillis());
 }
}

1.5获取当前线程

代码如下:

public class ThreadDemo {
 public static void main(String[] args) {
 Thread thread = Thread.currentThread();
 System.out.println(thread.getName());
 }
 }

二.线程中的几种状态

NEW:安排了工作,还未开始行动

RUNNABLE:可工作的,又可以分成正在工作中和即将开始工作

BLOCKED: 这几个都表示等着其他事情

WAITING:这几个都表示等着其他事情

TIMED_WAITING: 这几个都表示等着其他事情

TERMINATED:工作完成了

尾语

这篇博客到这里就结束啦,希望可以给大家带来帮助~~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值