多线程与并发编程【线程休眠、线程让步、线程联合、判断线程是否存活】(二)-全面详解(学习总结---从入门到深化)

news2024/9/27 12:08:42

 

 

目录

线程休眠

线程让步

线程联合

Thread类中的其他常用方法

判断线程是否存活

线程的优先级


 

线程休眠

 sleep()方法:可以让正在运行的线程进入阻塞状态,直到休眠时间 满了,进入就绪状态。sleep方法的参数为休眠的毫秒数。

public class SleepThread implements Runnable
{
    @Override
    public void run() {     
        System.out.println(Thread.currentThread().getName()+" 线程开始");
    for(int i=0;i<20;i++){
              System.out.println(Thread.currentThread().getName()+" "+i);
                try {
                    //线程休眠1秒
                    Thread.sleep(1000);
               } catch(InterruptedException e) {
                    e.printStackTrace();
               }
           }
      System.out.println(Thread.currentThread().getName()+" 线程结束");
   }
    public static void main(String[] args) {
        System.out.println("主线程开始");
        Thread t = new Thread(newSleepThread());
        t.start();
        System.out.println("主线程结束");
   }
}

线程让步

 yield()让当前正在运行的线程回到就绪状态,以允许具有相同优先 级的其他线程获得运行的机会。因此,使用yield()的目的是让具有 相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保 证yield()达到让步的目的,因为,让步的线程可能被线程调度程序 再次选中。

 使用yield方法时要注意的几点:

      1 yield是一个静态的方法。

      2 调用yield后,yield告诉当前线程把运行机会交给具有相同优先级的线程。

      3 yield不能保证,当前线程迅速从运行状态切换到就绪状态。

      4 yield只能是将当前线程从运行状态转换到就绪状态,而不能是等待或者阻塞状态。

public class TestyieldThread implements Runnable {
    @Override
    public void run() {
        for(int i=0;i<30;i++){
            if("Thread0".equals(Thread.currentThread().getName())){
                if(i == 0){
                    Thread.yield();
               }
           }
          System.out.println(Thread.currentThread().getName()+" "+i);
       }
   }
    public static void main(String[] args) {
        Thread t1 = new Thread(newTestyieldThread());
        Thread t2 = new Thread(newTestyieldThread());
        t1.start();
        t2.start();
   }
}

线程联合

 当前线程邀请调用方法的线程优先执行,在调用方法的线程执行结 束之前,当前线程不能再次执行。线程A在运行期间,可以调用线程 B的join()方法,让线程B和线程A联合。这样,线程A就必须等待线 程B执行完毕后,才能继续执行。

 join方法的使用

join()方法就是指调用该方法的线程在执行完run()方法后,再执行 join方法后面的代码,即将两个线程合并,用于实现同步控制。 

class A implements Runnable{
    private Thread b;
    public A(Thread b){
        this.b = b;
   }
    @Override
    public void run() {
        for(int i=0;i<10;i++){
          System.out.println(Thread.currentThread().getName()+" A "+i);
            if(i == 5){
                try {
                    this.b.join();
               } catch(InterruptedException e) {
                    e.printStackTrace();
               }
           }
            try {
                Thread.sleep(1000);} catch (InterruptedException e){
                e.printStackTrace();
           }
       }
   }
}
class B implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<20;i++){
          System.out.println(Thread.currentThread().getName()+" B "+i);
            try {
                Thread.sleep(1000);
           } catch (InterruptedException e){
                e.printStackTrace();
           }
       }
   }
}
public class TestJoinThread {
    public static void main(String[] args) {
        Thread t1 = new Thread(new B());
        Thread t = new Thread(new A(t1));
        t.start();
        t1.start();
 for(int i=0;i<10;i++){
          System.out.println(Thread.currentThread().getName()+" "+i);
            if(i ==2){
                try {
                    t.join();
               } catch(InterruptedException e) {
                    e.printStackTrace();
               }
           }
            try {
                Thread.sleep(1000);
           } catch (InterruptedException e){
                e.printStackTrace();
           }
       }
   }
}

线程联合案例

需求: 实现爸爸让儿子买烟。

/**
* 儿子买烟线程
*/
class SonThread implements Runnable{
    @Override
    public void run() {
        System.out.println("儿子出门买烟");
        System.out.println("儿子买烟需要10分钟");
        for(int i=0;i<10;i++){
            System.out.println("第"+i+"分钟");
            try {
                Thread.sleep(1000);
 } catch (InterruptedException e){
                e.printStackTrace();
           }
       }
        System.out.println("儿子买烟回来了");
   }
}
/**
* 爸爸抽烟线程
*/
class FatherThread implements Runnable{
    @Override
    public void run() {
        System.out.println("爸爸想抽烟,发现烟抽完了");
        System.out.println("爸爸让儿子去买一包红塔山");
        Thread t = new Thread(new SonThread());
        t.start();
        System.out.println("等待儿子买烟回来");
        try {
            t.join();
       } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("爸爸出门找儿子");
            System.exit(1);
       }
  System.out.println("爸爸高兴的接过烟,并把零钱给了儿子");
   }
}
public class TestJoinDemo {
    public static void main(String[] args) {
        System.out.println("爸爸和儿子买烟的故事");
        Thread t = new Thread(new FatherThread());
        t.start();
   }
}

Thread类中的其他常用方法

获取当前线程名称

方式一 this.getName()获取线程名称,该方法适用于继承Thread实现多线 程方式。

class GetName1 extends Thread{
    @Override
    public void run() {
        System.out.println(this.getName());
   }
}

方式二 Thread.currentThread().getName()获取线程名称,该方法适用于 实现Runnable接口实现多线程方式。

class GetName2 implements Runnable{
    @Override
    public void run() {
      System.out.println(Thread.currentThread().getName());
   }
}

设置线程的名称

方式一 通过构造方法设置线程名称。

class SetName1 extends Thread{
    public SetName1(String name){
        super(name);
   }
    @Override
    public void run() {
        System.out.println(this.getName());
   }
}
public class SetNameThread {
    public static void main(String[] args) {
        SetName1 setName1 = new SetName1("SetName1");
        setName1.start();
   }
}

方式二 通过setName()方法设置线程名称。

class SetName2 implements Runnable{
    @Override
    public void run() {
      System.out.println(Thread.currentThread().getName());
   }
}
public class SetNameThread {
    public static void main(String[] args) {
        Thread thread = new Thread(new SetName2());
        thread.setName("SetName2");
        thread.start();
   }
}

判断线程是否存活

 isAlive()方法: 判断当前的线程是否处于活动状态。 活动状态是指线程已经启动且尚未终止,线程处于正在运行或准备 开始运行的状态,就认为线程是存活的。

class Alive implements  Runnable{
    @Override
    public void run() {
        for(int i=0;i<4;i++){
          System.out.println(Thread.currentThread().getName()+" "+i);
            try {
                Thread.sleep(500);
           } catch (InterruptedException e){
                e.printStackTrace();
           }
       }
   }
}
public class TestAliveThread {
    public static void main(String[] args) {
        Thread thread = new Thread(newAlive());
        thread.setName("Alive");
        thread.start();
      System.out.println(thread.getName()+" "+thread.isAlive());
        try {
            Thread.sleep(4000);
       } catch (InterruptedException e) {
            e.printStackTrace();
       }
      System.out.println(thread.getName()+""+thread.isAlive());
   }
}

线程的优先级

 什么是线程的优先级

每一个线程都是有优先级的,我们可以为每个线程定义线程的优先 级,但是这并不能保证高优先级的线程会在低优先级的线程前执 行。线程的优先级用数字表示,范围从1到10,一个线程的缺省优 先级是5。 Java 的线程优先级调度会委托给操作系统去处理,所以与具体的操 作系统优先级有关,如非特别需要,一般无需设置线程优先级。

注意

线程的优先级,不是说哪个线程优先执行,如果设置某个线程 的优先级高。那就是有可能被执行的概率高。并不是优先执 行。

 线程优先级的使用

使用下列方法获得或设置线程对象的优先级。

1 int getPriority();

2 void setPriority(int newPriority);

注意:优先级低只是意味着获得调度的概率低。并不是绝对先 调用优先级高的线程后调用优先级低的线程。

class Priority implements Runnable{
    private int num = 0;
    private  boolean flag = true;
    @Override
    public void run() {
        while(this.flag){
          System.out.println(Thread.currentThread().getName()+" "+num++);
       }
   }
    public void stop(){  
        this.flag = false;
   }
}
public class PriorityThread {
    public static void main(String[] args)throws Exception {
        Priority p1 = new Priority();
        Priority p2 = new Priority();
        Thread t1 = new Thread(p1,"线程1");
        Thread t2 = new Thread(p2,"线程2");
        System.out.println(t1.getPriority());
        //Thread.MAX_PRIORITY = 10
        t1.setPriority(Thread.MAX_PRIORITY);
        //Thread.MAX_PRIORITY = 1
        t2.setPriority(Thread.MIN_PRIORITY);
        t1.start();
        t2.start();
        Thread.sleep(1000);
        p1.stop();
        p2.stop();
   }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/738295.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库常见4种范式

数据库范式 1. 数据库范式1.1 第一范式&#xff08;1NF&#xff09;1.2 第二范式&#xff08;2NF&#xff09;1.3 第三范式&#xff08;3NF&#xff09;1.4 巴斯科德范式&#xff08;BCNF&#xff09;1.5 范式的优缺点1.5.1 优点1.5.2 缺点 1. 数据库范式 在关系型数据库中&…

LabVIEW开发汽车安全带张紧测试

LabVIEW开发汽车安全带张紧测试 安全带是车辆乘员安全的主要约束系统&#xff0c;通过遮挡乘员与仪表板或挡风玻璃等接触&#xff0c;显着防止致命或非致命伤害。安全带的实践在三十年内将死亡率降低到相当可观的水平&#xff0c;并且直到今天仍然是许多国家的强制性。 然而&…

基于物理机部署前后端分离项目

软件安装 安装git 安装mysql 安装redis 安装python 安装虚拟环境 安装uwsgi 安装nginx centos安装常见软件_骑台风走的博客-CSDN博客一 卸载mysql### 1 查看mysql的安装情况 rpm -qa |grep -i mysql # -i表示忽略大小写 mysql80-community-release-el7-7.noarch mysql-commun…

如何用 Github Pages 免费部署静态站点

最低成本部署静态网站 所谓静态网站&#xff0c;是指它所有内容都是静态的&#xff0c;即预先编写好并存储在服务器上&#xff0c;访问者获取到的是事先准备好的静态文件。 所以完全不需要购买服务器&#xff0c;除了域名之外&#xff0c;几乎不会有其他花销。 我在构建五个静…

3.7.cuda运行时API-使用cuda核函数加速warpaffine

目录 前言1. warpAffine2. warpAffine案例2.1 导言2.2 main函数2.3 warpaffine_to_center_align函数2.4 warp_affine_bilinear函数2.5 warp_affine_bilinear_kernel核函数2.6 AffineMatrix结构体 3. 补充知识总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0…

【Linux后端服务器开发】软硬链接与动静态库

目录 一、软硬链接 二、动静态库 1. 静态库 2. 动态库 一、软硬链接 软链接&#xff1a;ln -s myfile soft_file.link 硬链接&#xff1a;ln myfile hard_file.link 查看映射关系&#xff1a;ll -li 软硬链接区别&#xff1a;是否具有独立的inode 软链接具有独立的inode…

Appium+python自动化(一)- 环境搭建—上(超详解)

最近整理了一下自动化的东西&#xff0c;先前整理的python接口自动化已经接近尾声。即将要开启新的征程和篇章&#xff08;Appium&python&#xff09;。那么首相的问题就是搭建环境了。好久没搭建环境又踩了不少坑&#xff0c;appium的环境搭建比较繁琐&#xff0c;好多同行…

零撸X2E大热门​Salad Venture的空投!

Salad Venture 随着Web3的走红&#xff0c;X to Earn成为热门概念&#xff0c;其中X可指运动、购物、游戏、学习和创作等诸多应用场景&#xff0c;Earn则是通过这些特定场景产生经济收益。与Web2企业将利益分配权牢牢掌握在自己手中不同&#xff0c;X to Earn的本质是将参与者…

Coggle 30 Days of ML(23年7月)任务七:训练TextCNN模型

Coggle 30 Days of ML&#xff08;23年7月&#xff09;任务七&#xff1a;训练TextCNN模型 任务七&#xff1a;使用Word2Vec词向量&#xff0c;搭建TextCNN模型进行训练和预测 说明&#xff1a;在这个任务中&#xff0c;你将使用Word2Vec词向量&#xff0c;搭建TextCNN模型进…

【LeetCode热题100】打卡第32天:最长连续序列只出现一次的数字单词拆分环形链表

文章目录 【LeetCode热题100】打卡第32天&#xff1a;最长连续序列&只出现一次的数字&单词拆分&环形链表⛅前言 最长连续序列&#x1f512;题目&#x1f511;题解 只出现一次的数字&#x1f512;题目&#x1f511;题解 单词拆分&#x1f512;题目&#x1f511;题解…

webAPI学习笔记5——移动端网页特效和本地存储

一、移动端网页特效 1. 触屏事件 1.1 触屏事件概述 移动端浏览器兼容性较好&#xff0c;我们不需要考虑以前 JS 的兼容性问题&#xff0c;可以放心的使用原生 JS 书写效果&#xff0c;但是移动端也有自己独特的地方。比如触屏事件 touch&#xff08;也称触摸事件&#xff09…

联想M7605DW怎么连接WiFi网络

联想M7605DW是一款拥有WiFi功能的打印机&#xff0c;可以通过WiFi连接无线网络&#xff0c;实现打印无线传输。 首先&#xff0c;需要确保你的WiFi网络已经正常连接&#xff0c;并且知道WiFI的网络名称和密码&#xff0c;同时确保你的电脑或手机设备与WiFi相连接。 启动联想M76…

数组、指针练习题及解析(含笔试题目讲解)其一

目录 前言 题目列表&#xff1a; 题目解析 一维数组 字符数组 字符串 字符指针 二维数组 笔试题 总结 前言 前几期的博客已经将有关指针、数组的所以知识都已基本讲解完毕&#xff0c;那么接下来我们就做一些练习巩固&#xff0c;这些练习依据历年来一些公司笔试题进行…

java的ThreadLocal变量

Java的ThreadLocal变量是线程的局部变量&#xff0c;只能被本线程访问&#xff0c;不能被其它线程访问&#xff0c;也就是说线程间进行了隔离。每个线程访问该变量的一个独立拷贝&#xff0c;互相不干扰。感觉跟synchronized的作用相反&#xff0c;synchronized是为了保护线程间…

Kafka入门,mysql5.7 Kafka-Eagle部署(二十五)

官网 https://www.kafka-eagle.org/ 下载解压 这里使用的是2.0.8 创建mysql数据库 创建名为ke数据库,新版本会自动创建&#xff0c;不会创建的话&#xff0c;自己手动创建&#xff0c;不然会报查不到相关表信息错误 SET NAMES utf8; SET FOREIGN_KEY_CHECKS 0;-- ------…

从2023中国峰会,看亚马逊云科技的生成式AI战略

“生成式AI的发展就像一场马拉松比赛&#xff0c;当比赛刚刚开始时&#xff0c;如果只跑了三四步就断言某某会赢得这场比赛&#xff0c;显然是不合理的。我们现在还处于非常早期的阶段。” 近日&#xff0c;在2023亚马逊云科技中国峰会上&#xff0c;亚马逊云科技全球产品副总裁…

智慧农业:温室大棚物联网系统,助力实现可视化科学管理

我国传统农业的特点是靠天吃饭&#xff0c;而智慧农业发端于物联网设备和对应的农业信息化管理系统&#xff0c;是利用数字技术、数据分析和人工智能等先进技术手段&#xff0c;对农业生产进行精细化管理和智能化决策的一种新型农业生产模式。它可以通过实时监测、预测和调控土…

java 配置打包Spring Boot项目过程中跳过测试环节

上文 java 打包Spring Boot项目&#xff0c;并运行在windows系统中中 我们演示了打包 Spring Boot项目的并运行在本地的方法 但是 我们这里会看到 每次打包 他这都会有个T E S T S 测试的部分 但是 我们自己开发的程序 要上线 有没有问题我们肯定自己清楚啊 没必要它做测试 而且…

web学习笔记2

文档流 网页是一个多层的结构&#xff0c;设置样式也是一层一层的设置&#xff0c;最终我们看到的最上面的一层。 文档流是网页最底层 我们创建的元素默认情况下&#xff0c;都在文档流中 元素分为两种状态&#xff1a;在文档流中&#xff0c;脱离文档流 元素在文档流中的特点 …

同一段数据分别做傅里叶变化和逆变换的结果及分析

已知有公式 D F T &#xff1a; X [ k ] ∑ n 0 N − 1 x [ n ] e − j 2 π k n N &#xff0c; 0 ≤ k ≤ N − 1 DFT&#xff1a;Χ[k]\sum_{n0}^{N-1}x[n]e^{-\frac{j2\pi kn}{N}}&#xff0c;0≤k≤N-1 DFT&#xff1a;X[k]n0∑N−1​x[n]e−Nj2πkn​&#xff0c;0≤k…