Thread 类的基本用法

本文介绍了Java中创建线程的多种方式,包括继承Thread类、实现Runnable接口、使用匿名内部类和Lambda表达式,以及使用Callable接口。同时,讨论了线程中断、线程等待(join())和线程休眠(sleep())的概念和用法。
摘要由CSDN通过智能技术生成

一、什么是Thread类

Thread类可以视为java标准库提供的一组解决多线程编程的一组API.创建好的Thread实例,和操作系统中的线程是一一对应的。操作系统提供了关于线程的API(C语言风格),java在对其进行封装就成Thread类。

二、线程的创建

2.1 继承Thread类

class MyThread extends Thread{

    @Override

    public void run() {

        //此时只是定义处理一个线程类,在系统中总是还没有创建出 新的线程。

        System.out.println("hello thread");

    }

}

public class TestDemo11 {

    public static void main(String[] args) {

        //创建线程

        Thread t = new MyThread();

        //启动线程,在系统中创建出了新的线程

        t.start();

    }

}

2.2实现Runnable接口中的run()方法

//Runnable其实就是描述一个任务

//创建一个类,实现Runnable接口,重写Runnable类中的run方法,在run()方法中,描述的是该线程要指向的哪些任务。

class MyThread2 implements Runnable{

    @Override

    public void run() {

        System.out.println("hello thread");

    }

}

public class TestDemo12 {

    public static void main(String[] args) {

        //创建线程,把创建好的Runnable实例传给Thread实例

        Thread t = new Thread(new MyThread2());

        t.start();

    }

}

2.3 利用匿名内部类

public class TestDemo14 {

    public static void main(String[] args) {

        Thread t1 = new MyThread(){

            @Override

            public void run() {

                System.out.println("hello thread1");

            }

        };

        Thread t2 = new Thread(new Runnable() {

            @Override

            public void run() {

                System.out.println("hello thread2");

            }

        });

        t1.start();

        t2.start();

    }

}

2.4 使用lambmd表达式

public class TestDemo15 {

    public static void main(String[] args) {

        //其实就是使用lambad表达式代替Runnable

        Thread t1 = new Thread(()->{

            //()表示无参的run()方法

            System.out.println("hello thread1");

        });

 

    }

}

2.5 使用Callable为接口,创建线程

 public static void main(String[] args) throws ExecutionException, InterruptedException {
//        Callable为接口  创建个任务
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
               int sum = 0;
                for (int i = 0; i <= 1000; i++) {
                    sum += i;
                }
                return sum;
            }
        };
//        创建线程执行任务
//        Thread不能直接传callable,需要在包装一层
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        Thread t = new Thread(futureTask);
        t.start();

//        get()获取上述任务结果
        System.out.println(futureTask.get());
    }

最常用的创建线程的方式为方法4,使用lambmd表达式。

定义出一个线程类,然后启动线程t.start(),其中start()方法决定系统是不是真的创建出线程。

三、线程中断 

中断线程简单的可以理解成为就是让该线程中的run()方法执行结束。还有一个特殊的就是main线程,如果想要中断main线程,那么就需要把main线程执行完。

3.1 中断线程方法:设置一个标志位

 public static boolean isQuit = false;

    public static void main(String[] args) {
        Thread t = new Thread(() ->{
            while (!isQuit){
                System.out.println("hello t");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(" t 线程终止");
        });

        t.start();

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        isQuit = true;
    }

3.2  调用 interrupt() 方法来通知

使用 Thread.interrupted() 或者 Thread.currentThread().isInterrupted() 代替自定
义标志位 .
Thread 内部包含了一个 boolean 类型的变量作为线程是否被中断的标记.
public class TestDemo21 {

    public static void main(String[] args) {

        Thread t = new Thread(()->{

           while(!Thread.currentThread().isInterrupted()) {

               System.out.println("hello thread");

               try {

                   Thread.sleep(1000);

               } catch (InterruptedException e) {

                   e.printStackTrace();

               }

           }

        });

        //启动t线程

        t.start();

        //在main线程中中断t线程

        //5s之后中断t线程

        try {

            Thread.sleep(5000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        t.interrupt();

    }

}

四 线程等待

使用join()方法,这个方法就是让线程与线程之间,有了一定的执行顺序。我们知道在多线程中的调度是随机的,不确定的,多线程的执行靠调度器安排,该调度器的安排是随机的,不规律的。其实线程等待就是一个行之有效的方法,实际上就是控制线程执行的先后顺序。

 线程的等待 (Join())
    //main线程调用join()时候,如果t还在运行,此时main线程阻塞,直到 t 执行完毕,main才从阻塞中解除,继续执行
    //main线程调用join()时候,如果t已经结束,此时main立即执行
   //都能保证 t 先执行
     public static void main(String[] args) throws  InterruptedException{
        Thread t = new Thread(() ->{
            System.out.println("hello t");
        });

        t.start();

        t.join();

         System.out.println("hello main");
     }

五 线程的休眠

其实线程休眠就是调用Thread.sleep()方法。

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());
   }
}

六、获取线程实例

一般我们就会通过Thread.currentThread()来获取线程实例,在 Thread 类中,currentThread是一个静态且本地方法。

 public static void main(String[] args) {
         // currentThread()是获取到当前线程的实例
        //此处 currentThread 得到的对象就是 t
        Thread t = new Thread(() ->{
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("hello t");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
            }
            System.out.println(" t 线程终止");
        });

        t.start();

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // interrupt()的作用
        //把 t 内部的标志位设置成 ture
        //如果该线程处于阻塞状态可以将该线程唤醒
        t.interrupt();
    }

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值