Java基础进阶线程中的常用方法

简介: Java基础进阶线程中的常用方法

一、获取线程的名字


String name = 线程对象.getName();

修改线程对象的名字

线程对象.setName("线程名字");

当线程没有设置名字的时候,默认的名字有什么规律?(了解一下)

   Thread-0

   Thread-1

   Thread-2

   Thread-3


二、获取当前线程对象


Thread t = Thread.currentThread();

返回值t就是当前线程。


示例代码01:


public class ThreadTest05 {
    public static void doSome(){
        //这样就不行了
        //this.getName();
        //super.getName();
        // 但是这样可以
        String name = Thread.currentThread().getName();
        System.out.println("-->" + name);
    }
    public static void main(String[] args) {
        //创建分支线程对象
        MyThread2 t1 = new MyThread2();
        //调用doSome方法()
        ThreadTest05.doSome();
        //获取当前的线程对象
        // currentThread就是当前线程对象
        // 这个代码出现在main方法当中,所以当前线程就是主线程。
        Thread currentThread = Thread.currentThread();
        System.out.println(currentThread.getName());
        //获取线程名字
        String n1 = t1.getName();
        System.out.println(n1);
        //修改线程名字
        t1.setName("tttt");
        System.out.println(t1.getName());
        //创建第二个多线程对象
        MyThread2 t2 = new MyThread2();
        System.out.println(t2.getName());
        t2.setName("ssss");
        System.out.println(t2.getName());
        t2.start();
        //启动线程
        t1.start();
    }
}
class MyThread2 extends Thread{
    public void run(){
        for(int i=0;i<100;i++){
            //当前线程对象
            Thread currentThread = Thread.currentThread();
            System.out.println(currentThread().getName() + "-->" + i);
        }
    }
}


运行结果:


0a2653c851af460fa595bd959398a8f1.png


三、线程的sleep方法


关于线程的sleep方法:


static void sleep(long millis)


1、静态方法:Thread.sleep(1000);

2、参数是毫秒

3、作用:让当前线程进入休眠,进入“阻塞状态”,放弃占有CPU时间片,让给其它线程使用。


这行代码出现在A线程中,A线程就会进入休眠。

这行代码出现在B线程中,B线程就会进入休眠。

4、Thread.sleep()方法,可以做到这种效果:


间隔特定的时间,去执行一段特定的代码,每隔多久执行一次。


示例代码02:


public class ThreadTest06 {
    public static void main(String[] args) {
        //sleep方法让当前线程休眠指定时间,此处休眠5秒
        /*try {
        // 让当前线程进入休眠,睡眠5秒
        // 当前线程是主线程!!!
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("HelloWorld!");*/
        //此处每循环一次,就休眠一秒
        for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName() + "--->" + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


运行结果:


2d65d23f6d4748949b924e4057485923.png


四、sleep方法的面试题


分支线程调用sleep方法,会休眠分支线程吗?


示例代码03:


public class ThreadTest07 {
    public static void main(String[] args) {
        //多态
        Thread t= new MyThread3();
        //修改名字
        t.setName("t");
        //启动分支线程
        t.start();
        try {
            // 问题:这行代码会让线程t进入休眠状态吗?
            // 在执行的时候还是会转换成:Thread.sleep(1000 * 5);
            // 这行代码的作用是:让当前线程进入休眠,也就是说main线程进入休眠。
            // 这样代码出现在main方法中,main线程睡眠。
            t.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("HeloWorld!");
    }
}
class MyThread3 extends Thread{
    public void run(){
        for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName() + "--->" + i);
        }
    }
}


运行结果:


6de278e6d6694ce5bb08e7e842b7e74b.png


五、终止线程的休眠


sleep睡眠太久了,如果希望半道上醒来,你应该怎么办?也就是说怎么叫醒一个正在睡眠的线程??


注意:这个不是终断线程的执行,是终止线程的睡眠。


调用interrupt方法终止休眠的线程


示例代码04:


public class ThreadTest08 {
    public static void main(String[] args) {
        //创建线程接口实现类对象
        Thread t = new Thread(new MyRunnable2());
        t.setName("t");
        t.start();
        // 希望5秒之后,t线程醒来(5秒之后主线程手里的活儿干完了。)
        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 终断t线程的睡眠(这种终断睡眠的方式依靠了java的异常处理机制。)
        t.interrupt();// 干扰,一盆冷水过去!
    }
}
class MyRunnable2 implements Runnable{
    // 重点:run()当中的异常不能throws,只能try catch
    // 因为run()方法在父类中没有抛出任何异常,子类不能比父类抛出更多的异常。
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "---> begin");
        try {
            // 睡眠1年
            Thread.sleep(1000 * 60 * 60 * 24 * 365);
        } catch (InterruptedException e) {
            // 打印异常信息
            //e.printStackTrace();
//            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "---> end");
        // 调用doOther
        //doOther();
    }
    // 其它方法可以throws
    /*public void doOther() throws Exception{
    }*/
}


运行结果:


8ec4f2997fb246878c34ecd6d122b7c6.png


六、强行终止线程的执行


调用现成的stop方法(此方法已过时)


在java中怎么强行终止一个线程的执行。

这种方式存在很大的缺点:容易丢失数据。因为这种方式是直接将线程杀死了,

线程没有保存的数据将会丢失。不建议使用。


示例代码05:


public class ThreadTest09 {
    public static void main(String[] args) {
        Thread t = new Thread(new MyRunnable3());//出错点,看清构造器中的实现类,别写错
        t.setName("t");
        t.start();
        //模拟5秒,设置5秒终止
        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //强制终止线程t//5秒后强制终止线程
        t.stop();//已过时
    }
}
class MyRunnable3 implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName() + "--->" + i);
            //休眠一秒
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


运行结果:


12c3b7f3f8814309a195c64f051d4445.png


七、合理的终止一个线程的方法


使用if()循环的Return方法合理终止一个线程


示例代码06:


public class ThreadTest10 {
    public static void main(String[] args) {
        MyRunnable4 m = new MyRunnable4();
        Thread t = new Thread(m);
        t.setName("t");
        t.start();
        //模拟5秒
        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //当5秒后把线程休眠标记设置为false,线程终止,不会导致数据丢失
        m.run = false;
    }
}
class MyRunnable4 implements Runnable{
    //定义线程休眠标记
    boolean run = true;
    @Override
    public void run() {
       for(int i=0;i<10;i++){
           if(run){
               System.out.println(Thread.currentThread().getName() + "--->" + i);
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }else{
               // return就结束了,你在结束之前还有什么没保存的。
               // 在这里可以保存呀。
               //save....
               //终止当前线程
               return;
           }
       }
    }


运行结果:


34e8d716411043c08c7ffba9fbba23de.png


八、线程调度概述


常见的线程调度模型有哪些?


1、抢占式调度模型:


那个线程的优先级比较高,抢到的CPU时间片的概率就高一些/多一些。

java采用的就是抢占式调度模型。

2、均分式调度模型:


平均分配CPU时间片。每个线程占有的CPU时间片时间长度一样。

平均分配,一切平等。

有一些编程语言,线程调度模型采用的是这种方式。

3、线程调度的方法


实例方法:


void setPriority(int newPriority) 设置线程的优先级

int getPriority() 获取线程优先级

最低优先级1

默认优先级是5

最高优先级10

优先级比较高的获取CPU时间片可能会多一些。(但也不完全是,大概率是多的。)


示例代码07:


public class ThreadTest11 {
    public static void main(String[] args) {
        System.out.println("线程的最高优先级:" + Thread.MAX_PRIORITY);
        System.out.println("线程的最低优先级:" + Thread.MIN_PRIORITY);
        System.out.println("线程的默认优先级:" + Thread.NORM_PRIORITY);
        Thread.currentThread().setPriority(1);
        System.out.println(Thread.currentThread().getPriority());
        // main线程的默认优先级是:5
        //System.out.println(currentThread.getName() + "线程的默认优先级是:" + currentThread.getPriority());
        Thread t = new Thread(new MyRunnable5());
        t.setPriority(10);
        t.setName("t");
        t.start();
        // 优先级较高的,只是抢到的CPU时间片相对多一些。
        // 大概率方向更偏向于优先级比较高的。
        for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName() + "--->" + i);
        }
    }
}
class MyRunnable5 implements Runnable{
    public void run(){
        // 获取线程优先级
        //System.out.println(Thread.currentThread().getName() + "线程的默认优先级:" + Thread.currentThread().getPriority());
        for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName() + "--->" + i);
        }
    }
}


运行结果:


92ba0822ed0b46e1ae72df8a17d3a45b.png


九、线程让位


让位,当前线程暂停,回到就绪状态,让给其它线程。


静态方法:


static void yield() 让位方法

暂停当前正在执行的线程对象,并执行其他线程

yield()方法不是阻塞方法。让当前线程让位,让给其它线程使用。

yield()方法的执行会让当前线程从“运行状态”回到“就绪状态”。

注意:在回到就绪之后,有可能还会再次抢到。


示例代码08:


public class ThreadTest12 {
    public static void main(String[] args) {
        Thread t = new Thread(new MyRunnable6());
        t.setName("t");
        t.start();
        for(int i=1;i<1000;i++){
            System.out.println(Thread.currentThread().getName() + "--->" + i);
        }
    }
}
class MyRunnable6 implements Runnable{
    @Override
    public void run() {
        for(int i=1;i<1000;i++){
            //每100个让位一次。
            if(i % 100 == 0){
                Thread.yield();// 当前线程暂停一下,让给主线程。v
            }
            System.out.println(Thread.currentThread().getName() + "--->" + i);
        }
    }
}


运行结果:


d79b274929334152a6d38be91e2d1be3.png


十、线程合并


实例方法:void join()


示例代码09:


public class ThreadTest13 {
    public static void main(String[] args) {
        System.out.println("main ---> begin!");
        Thread t = new Thread(new MyRunnable7());
        t.setName("t");
        t.start();
        //合并线程
        try {
            t.join();//t合并到当前线程中,当前线程受阻塞,t线程执行直到结束
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("main ---> over");
    }
}
class MyRunnable7 implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<1000;i++){
            System.out.println(Thread.currentThread().getName() + "--->" + i);
        }
    }
}


运行结果:

dfc80ca9d8004e6c9ddc00e8448ffc6a.png

目录
打赏
0
0
0
0
4
分享
相关文章
|
25天前
|
【Java并发】【线程池】带你从0-1入门线程池
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是编写高端CRUD应用。2025年我正在沉淀中,博客更新速度加快,期待与你一起成长。 线程池是一种复用线程资源的机制,通过预先创建一定数量的线程并管理其生命周期,避免频繁创建/销毁线程带来的性能开销。它解决了线程创建成本高、资源耗尽风险、响应速度慢和任务执行缺乏管理等问题。
157 60
【Java并发】【线程池】带你从0-1入门线程池
|
11天前
|
《从头开始学java,一天一个知识点》之:方法定义与参数传递机制
**你是否也经历过这些崩溃瞬间?** - 看了三天教程,连`i++`和`++i`的区别都说不清 - 面试时被追问&quot;`a==b`和`equals()`的区别&quot;,大脑突然空白 - 写出的代码总是莫名报NPE,却不知道问题出在哪个运算符 🚀 这个系列就是为你打造的Java「速效救心丸」!我们承诺:每天1分钟,地铁通勤、午休间隙即可完成学习;直击痛点,只讲高频考点和实际开发中的「坑位」;拒绝臃肿,没有冗长概念堆砌,每篇都有可运行的代码标本。上篇:《输入与输出:Scanner与System类》 | 下篇剧透:《方法重载与可变参数》。
43 25
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
66 23
|
5天前
|
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
18 1
Java中的异常处理方法
本文深入剖析Java异常处理机制,介绍可检查异常、运行时异常和错误的区别与处理方式。通过最佳实践方法,如使用合适的异常类型、声明精确异常、try-with-resources语句块、记录异常信息等,帮助开发者提高代码的可靠性、可读性和可维护性。良好的异常处理能保证程序稳定运行,避免资源泄漏和潜在问题。
|
19天前
|
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
45 5
Java容器及其常用方法汇总
Java Collections框架提供了丰富的接口和实现类,用于管理和操作集合数据。
Java容器及其常用方法汇总
|
1月前
|
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
166 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
21天前
|
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
当我们创建一个`ThreadPoolExecutor`的时候,你是否会好奇🤔,它到底发生了什么?比如:我传的拒绝策略、线程工厂是啥时候被使用的? 核心线程数是个啥?最大线程数和它又有什么关系?线程池,它是怎么调度,我们传入的线程?...不要着急,小手手点上关注、点赞、收藏。主播马上从源码的角度带你们探索神秘线程池的世界...
91 0
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
129 14
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等