Thread 类的基本用法

一、线程的创建

1.1 Thread的常见构造方法

  方法

说明
Thread() 创建线程对象
Thread(Runnable target)  使用Runnable对象创建线程对象
Thread(String name)    创建线程对象,并命名
Thread(Runnable target,String name)   使用Runnable对象创建线程对象,并命名

1.2 继承Thread的方式创建线程

public class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("t");
    }
 
    public static void main(String[] args) {
        MyThread t=new MyThread();
        t.start();//启动线程
        System.out.println("main");//主线程的打印
    }
}

MyThread 类继承了 Thread 类,并重写了 run() 方法。创建 MyThread 的实例并通过调用 start() 方法来启动新线程。

1.2 通过实现Runnable接口创建线程

创建一个实现 Runnable 接口的新类,并实现 run() 方法。然后,将这个类的实例传递给 Thread 类的构造函数。

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

1.3 使用匿名内部类创建线程

创建一个匿名内部类,同时继承 Thread 类或实现 Runnable 接口,并在创建时定义线程任务。

//使用匿名内部类实现继承thread
public class ThreadDemo3 {
    public static void main(String[] args) {
        Thread t=new Thread(){
            @Override
            public void run(){
            while (true){
                System.out.println("t");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            }
        };
        t.start();
        while (true){
            System.out.println("main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

另外一种实现runable接口的方式去实现线程的创建

//匿名内部类实现ThreadRunable接口

public class ThreadDemo4 {
    public static void main(String[] args) {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("t");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
        while (true){
            System.out.println("main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

1.4 使用lambda 表达式创建 Runnable 子类对象

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

使用lambda表达式是为了使代码看起来更加简洁,跟其他创建线程方法功能一样,除此之外,工作中使用的最多的也是这种

1.5 start方法和run方法的区别

run() 方法 只是线程的一个普通方法,调用它不会创建一个新的线程,而只是按顺序执行其中的代码。因此,如果直接调用 run() 方法,那么其中的代码会在当前线程中执行,不会开启新的线程。

start() 方法 才是真正启动一个新线程并开始执行其中的 run() 方法。当调用 start() 方法时,Java 会创建一个新的线程,并在新的线程中执行 run() 方法中的代码。因此,如果要启动一个新线程并执行其中的代码,就必须使用 start() 方法。

当主线程main调用t.start()方法的时候,另外一个线程就已经启动,开始执行run方法.代表另一个线程线程已经开始,但同时主线程也在启动.进而产生并发.

二.线程中断

线程中断是指在多线程程序中,中断正在运行的线程的执行,通常是由其他线程通过调用目标线程的interrupt()方法来实现。被中断的线程可以捕获这个中断信号并做出相应的处理。

2.1 interrupt()方法

interrupt() 方法是一种请求中断线程的机制。它不会立即停止线程的执行,而是设置线程的中断状态,使线程能够根据这个状态来决定自己的行为。interrupt() 方法是 Thread 类的一个实例方法,可以被任何其他线程调用,用来请求中断目标线程。

1. 设置中断状态:当 interrupt() 方法被调用时,它会将目标线程的中断状态设置为 true。

2. 线程检查中断状态:线程需要定期检查自己的中断状态。这通常在执行关键操作之后或者在循环的检查点进行。

3. 响应中断:线程可以选择响应中断状态,执行必要的清理工作,并安全地退出。线程也可以选择忽略中断状态,继续执行。

class InterruptibleTask implements Runnable {
    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                // 执行任务
                Thread.sleep(1000); // 休眠1秒
                System.out.println("执行任务");
            } catch (InterruptedException e) {
                // 处理中断
                System.out.println("程序已经被中断了");
                // 清理资源
                return; // 退出run方法
            }
        }
    }
}
 
public class test {
    public static void main(String[] args) {
        Thread taskThread = new Thread(new InterruptibleTask());
        taskThread.start();
 
        // 让任务线程运行一段时间
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
 
        // 请求中断任务线程
        taskThread.interrupt();
        System.out.println("请求中断");
    }
}

InterruptibleTask 在一个循环中执行任务,并在每次迭代后检查是否被中断。当主线程调用 taskThread.interrupt() 时,任务线程会捕获 InterruptedException 并安全地退出。 

2.2 interrupted()方法

interrupted() 是 Java 中 Thread 类的一个静态方法,它用于检查当前线程的中断状态,并且与 isInterrupted() 方法不同,interrupted() 在检查后会清除中断状态。这个方法通常用于流式操作中,以便在处理中断时能够保持中断状态的一致性。

检查中断状态:interrupted() 方法检查当前线程的中断状态。

清除中断状态:无论中断状态如何,interrupted() 方法都会将中断状态重置为未中断(false)。

返回中断状态:该方法返回当前线程的中断状态。

public class Demo {
    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();
   }
}

3.isInterrupted()方法 

在Java中,isInterrupted()方法是用来检查线程的中断状态,但不会清除线程的中断状态。这个方法是一个实例方法,可以通过Thread类的实例来调用。

查询中断状态:isInterrupted() 方法检查调用它的线程的中断状态。

返回中断状态:该方法返回一个布尔值,表示线程的中断状态。如果线程被中断过,或者中断状态被设置过,它将返回 true。

中断状态不清除:调用 isInterrupted() 方法后,线程的中断状态保持不变。

package threrading;

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

        t.start(); 

       
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
      
        t.interrupt();  

  
    }
}

三、线程等待

有时,我们需要等待一个线程完成它的工作后,才能进行自己的下一步工作。例如,张三只有等李四转 账成功,才决定是否存钱,这时我们可以使用join方法明确等待线程的结束。

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

阻塞等待:当线程A调用线程B的join()方法时,线程A会暂停执行,直到线程B的run()方法执行完毕。
释放锁:在join()方法调用期间,线程A会释放它持有的任何同步锁,这允许其他线程在这些锁上操作。
继续执行:一旦线程B完成执行,线程A会解除阻塞,并继续执行join()方法之后的代码。

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        Runnable target = () -> {
            for (int i = 0; i < 5; 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("王五工作结束了");
   }
}

四、线程休眠

线程休眠是通过 Thread 类中的 sleep() 方法实现的。当一个线程调用 sleep() 方法时,它会进入休眠状态,暂停执行一段时间,然后重新开始执行。

方法  

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

五、获取当前线程引用

获取线程的实例非常的简单,就是调用Thread.currentThread()方法,因为线程的调度是不可控的,所以,这个方法只能保证实 际休眠时间是大于等于参数设置的休眠时间的。

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

  • 33
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Starry灬

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

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

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

打赏作者

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

抵扣说明:

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

余额充值