Thread类的基本用法

线程创建

通过Thread类创建

通过继承 Thread 类并重写run方法就可以实现多线程;在 Thread 类中 提供了start方法启动新线程

class MyThread extends Thread{
    public void run(){
        System.out.println("MyThread中的run方法已执行");
    }
}
public class Main{
    public static void main(String[] args) {
        MyThread t=new MyThread();
        Thread thread=new Thread(t);
        thread.start();
    }
}

 通过Runnable接口创建

java只支持单继承,如果一个类继承了某个父类就没办法再继承 Thread 类了,因此,Thread类提供了另一种构造方法Thread (Runnable target)构传的参数实现了Runnable接口的对象,Runnable接口中只有一个run方法,创建线程时实现Runnable接口中的run方法作为运行代码,不需要再调用Thread类中的run方法。

class MyThread implements Runnable{
    public void run(){
        System.out.println("Runnable接口创建的线程已运行");
    }
}
public class Main{
    public static void main(String[] args){
        MyThread runnable=new MyThread();
        Thread thread=new Thread(runnable);
        thread.start();
    }
}

通过Callable接口创建

在以上两种方法中创建线程的时候,里面的run方法都没有返回值,如果想要在run方法中获取返回值,就可以通过Callable接口来创建线程

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ExecutionException;

class MyThread4 implements Callable<Object>{
    @Override
    public Object call() throws Exception {
        System.out.println("call方法已执行");
        return 0;
    }
}
class Main{
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyThread4 mt=new MyThread4();
        FutureTask<Object> ft=new FutureTask<>(mt);
        Thread thread=new Thread(ft,"thread");
        thread.start();
        //获取返回值
        System.out.println(ft.get());
    }
}

Callable 接口的实现的多线程是通过 FutureTask 类来进行封装和管理返回结果的,FutureTask 类的直接父接口是RunnableFuture,想必从名字我们就能看出它一定跟Runnable 接口有关系。RunnableFuture是Runnable和Future的结合体。看下图它们之间的关系:

 

 在上图中我们可以看出,FutureTask是 Runnable 接口与 Future 接口的实现类。

线程创建的方式有多种,这里只列举了三种

其实严格来说,线程的创建方式只有通过new Thread().start()来创建,不管通过哪种方式最终都需要通过new Thread().start()创建。更加详细的描述可以看这篇文章大家都说Java有三种创建线程的方式!并发编程中的惊天骗局!

线程中断

线程中断指的是在线程运行过程中,手动中断线程的执行。

比如说,我写了一个多线程的代码,线程正在执行中,但是因为网速太辣鸡导致线程一直处于运行的状态,它不结束,我想停掉这个线程。

在 java 中执行线程中断有两个常用的方法:

  • 通过共享的标记进行中断
  • 使用 interrupt() 方法中断

第一种:

使用自定义的标志位

public class ThreadDemo {
    private static class MyRunnable implements Runnable{
        public volatile boolean isStop=false;
        public void run(){
            while(!isStop){
                System.out.println(Thread.currentThread().getName()+"正在加载中……");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyRunnable target=new MyRunnable();
        Thread thread=new Thread(target);
        thread.start();
        Thread.sleep(10*1000);
        target.isStop=true;
        System.out.println("线程已中断");
    }
}

第二种:

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

public void interrupt()  中断对象关联的线程,如果线程正阻塞,通过异常来通知,否则设置标志位

public class ThreadDemo{
    private static class MyRunnable implements Runnable{
        @Override
        public void run(){
            while( !Thread.interrupted()){//或者  !Thread.interrupted()
                System.out.println(Thread.currentThread().getName()+"正在加载中……");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println("线程已中断");
                    break;
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyRunnable target=new MyRunnable();
        Thread thread=new Thread(target);
        thread.start();
        Thread.sleep(10*1000);
        thread.interrupt();

    }
}

线程等待 -join()

有时候,我们想要在某个线程结束后再执行后面的任务,我们就需要线程等待,假如月光族张三想换个新手机,但是发现老板还没发工资,他就没钱买,只能等到老板发工资后再买

public class ThreadDemo3 {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable=()->{
            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(runnable,"老板");
        Thread thread2=new Thread(runnable,"张三");
        thread1.start();
        thread1.join();
        thread2.start();
        thread2.join();
        System.out.println("张三买到手机了");
    }
}

线程休眠

让线程休眠的方法如下:

  • public static void sleep(long millis) throws InterruptedException  休眠当前线程millis毫秒
  • public static void sleep(long millis,int nanos)throws InterruptedException 更高精度的休眠
public class ThreadDemo1 {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("当前时刻:"+System.currentTimeMillis());
        Thread.sleep(3000);
        System.out.println("当前时刻:"+System.currentTimeMillis());
    }
}

获取线程实例

我们可以通过以下的方法进行获取:

public static Thread currentThread();

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值