Thread 类的基本用法

前言

Thread 类是 Java 中用于创建和管理线程的类。在 Java 中,每个程序至少有一个线程,也就是主线程。使用 Thread 类,可以创建新的线程并与主线程并行执行.Thread类的基本用法有以下几种方式:


Thread类的基本用法有以下几种方式: 

1.继承Thread类 

class Mythread extends Thread{
    @Override
    public void run() {
        //这个方法是线程的入口方法
        while (true){
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}
public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t =new Mythread();
        //t.run();
        t.start();
        while (true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }

    }
}

2. 继承Thread匿名内部类

public class Demo2 {
    public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                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);
            }
        }
    }
}


 3.实现Runnable接口

class MyRunnable implements  Runnable{
    @Override
    public void run() {
        while (true){
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
public class Demo3 {
    public static void main(String[] args) {
        Runnable runnable =new MyRunnable();
        Thread t =new Thread(runnable);
        t.start();
        while (true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }

    }
}

 与直接继承Thread的区别是,这个方法能解耦合,如果一个类需要运行在一个新的线程上,那么通过实现Runnable接口,我们可以把这个类和Thread类进行解耦合,这样修改这个类的代码就不需要修改Thread类的代码,反之亦然.


 4.实现Runnable接口匿名内部类
public class Demo4 {
    public static void main(String[] args){
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
       Thread t =new Thread(runnable);
        t.start();
        while (true){
            System.out.println("hello main");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

5 .使用Lambda表达式
public class Demo5 {
    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. 通过共享的标记来进行沟通

public class Demo6 {  
    private static volatile boolean isQuit = false;  
    public static void main(String[] args) throws InterruptedException {  
        Thread t = new Thread(() -> {  
            while (!isQuit) {  
                System.out.println("线程工作中");  
                try {  
                    Thread.sleep(1000);  
                } catch (InterruptedException e) {  
                    throw new RuntimeException(e);  
                }  
            }  
            System.out.println("线程工作完毕");  
        });  
        t.start();  
        Thread.sleep(5000);  
        isQuit = true;  
        System.out.println("设置isQuit为true");  
    }  
}

这个方式需要给标志位上加 volatile 关键字,确保isQuit的可见性.

2.使用Thread自带的标志位来控制线程是否要停止

public class Demo7 {
  
   public static void main(String[] args){
        Thread t = new Thread(()->{
            //Thread 类内部有一个现成的标志位,可以用来判定当前的循环是否要结束
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("线程工作中");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });
        t.start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("让t线程中止");
        t.interrupt();

    }
}
如果线程因为调用 wait/join/sleep 等方法而阻塞挂起,则以 InterruptedException 异常的形式通
知,清除中断标志
当出现 InterruptedException 的时候 , 要不要结束线程取决于 catch 中代码的写法 . 可以选择
忽略这个异常 , 也可以跳出循环结束线程.如果你希望在线程t休眠时立即中断它,那么你可以在调用 Thread.sleep(1000)的地方捕获InterruptedException异常,并在捕获到异常后立即退出循环,例如:
public class Demo8{


        public static void main(String[] args){
            Thread t = new Thread(()->{
                //Thread 类内部有一个现成的标志位,可以用来判定当前的循环是否要结束
                while (!Thread.currentThread().isInterrupted()){
                    System.out.println("线程工作中");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // 如果线程被中断,立即退出循环
                        break;
                    }
                }
            });
            t.start();
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("让t线程中止");
            t.interrupt();
        }
    }


三.线程等待

用Thread中的join()方法来操作线程等待

public class Demo9 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            for (int i = 0; i <5 ; i++) {
                System.out.println("t线程工作中!");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
        });
        t.start();
        //一旦调用join,主线程就会触发阻塞,让主线程来等待t线程执行结束
        //一直阻塞到t执行完毕了,join才会解除阻塞,才能继续执行
        System.out.println("join等待开始");
        t.join();
        System.out.println("join等待结束");
    }
}
public void join()
等待线程结束
public void join(long millis)
等待线程结束,最多等 millis 毫秒
public void join(long millis, int nanos)
同理,但可以更高精度

 四.线程休眠

在Java中,可以使用Thread.sleep()方法来暂停当前线程的执行。这个方法需要一个表示休眠时间的参数,单位是毫秒。

public class Demo10 {
    public static void main(String[] args) throws InterruptedException {
        long beg =System.currentTimeMillis();
        Thread.sleep(1000);
        long end = System.currentTimeMillis();
        System.out.println("时间"+(end -beg)+"ms");
    }
}
因为线程的调度是不可控的,所以,这个方法只能保证实
际休眠时间是大于等于参数设置的休眠时间,而不能保证线程正好休眠1秒,它只能保证线程至少休眠1秒。 Thread.sleep的时间参数是一个毫秒数,而操作系统的调度器是以毫秒为单位进行调度的,因此存在一定的误差。 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值