Java高效率复习-线程基础[线程]

news2024/11/13 20:04:15

内容大纲

在这里插入图片描述

线程相关概念

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

并发并行

在这里插入图片描述
在这里插入图片描述
当只有一个CPU时,会执行并发的效果,在多个应用程序之间快速切换,而有多个CPU时,则多个CPU独立执行,而当进程多于CPU个数时,则会出现并发+并行的情况,总有一个CPU需要来回切换从而并发。
查看电脑CPU个数的API

public static void main(String[] args) {
    Runtime runtime = Runtime.getRuntime();
    int i = runtime.availableProcessors();
    System.out.println("当前电脑的CPU个数为:"+i);
}

在这里插入图片描述

线程的基本使用

创建线程

创建线程的两种方式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

线程创建案例

在这里插入图片描述

class Cat extends Thread{//继承Thread类,来重写run()方法,该run()方法也是Thread类对Runnable接口的实现
    @Override
    public void run() {
        while(true){//无限循环广播
            //super.run();重写run方法,写上自己的业务逻辑
            //要求:每隔1秒中输出:迷你深渊冰龙
            System.out.println("<>迷你深渊冰龙<>");
            //让线程休眠1秒钟
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在这里插入图片描述
run()方法会被对象的start()方法调用,在run()方法中调用的sleep(),表示线程休眠,参数是毫秒值,1000=1秒

多线程机制

在这里插入图片描述
即使是main线程结束,但是如果main的子线程还没有结束,那么这个进程就不会结束。进程=Application

Start()方法

为什么在main方法中调用的是start(),而不是run()方法?
在这里插入图片描述
如果此处是cat.run(),那么当主线程启动时,执行将又变成顺序执行,此时run()方法里输出的线程名就不再是Thread-0,而是main,也就是说,start()方法才是真正开启了一个线程,run()方法只是声明线程要执行的内容,下面是start方法的底层。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Runnable创建线程

在这里插入图片描述
在这里插入图片描述

多线程案例

在这里插入图片描述

继承Thread和实现Runnable的区别

在这里插入图片描述

多线程售票问题

在这里插入图片描述
在这里插入图片描述
不论是使用继承Thread还是实现Runnable接口都会出现超卖的情况,原因是三个线程都进入了判断,轮流执行减票的情况。

通知线程退出

下面代码有一个线程类t1,该类会通过while循环一直打印语句到控制台,while的判断条件是loop变量,我们设置了setLoop()方法,在主线程中,让主线程休眠10秒后,进行setLoop(false),也就是通知t1线程停止。
在这里插入图片描述

package com.hspdu.thread;

public class ThreadExit {
    public static void main(String[] args)throws Exception {
        T t1 = new T();
        t1.start();
        //如果希望main线程去控制t1线程的终止,必须可以修改loop变量
        //让t1退出true循环,从而终止t1线程 -> 通知方式
        //让主线程休眠十秒,再通知t1退出
        Thread.sleep(10*1000);
        t1.setLoop(false);
    }
}
class T extends Thread{
    private int count = 0;
    private boolean loop = true;

    public void setLoop(boolean loop) {
        this.loop = loop;
    }

    @Override
    public void run() {
        while(loop){
            try{
                Thread.sleep(50);//让当前线程休眠10ms
            }catch (Exception ex){
                ex.printStackTrace();
            }
            System.out.println("T 运行中..."+(++count));
        }
    }
}

线程中断和线程常用方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.hspdu.thread;

public class ThreadMethodTest {
    public static void main(String[] args)throws InterruptedException {
        MyThread t = new MyThread();
        t.setName("沙鹰-天神");//自定义线程名
        t.setPriority(Thread.MIN_PRIORITY);//最小优先级 = 1
        t.start();//启动子线程
        //主线程打印5个hi,然后就中断 子线程休眠
        for (int i = 0; i <5 ; i++) {
            Thread.sleep(1000);
            System.out.println("hi"+i);
        }
        System.out.println(t.getName()+" 线程的优先级 = "+t.getPriority());
        //当执行到这里时就会中断t线程的休眠
        t.interrupt();//中断t线程
    }
}
class MyThread extends Thread{
    @Override
    public void run() {
        while(true){
            for (int i = 0; i < 100 ; i++) {
                //Thread.currentThread().getName() 获取当前线程名称
                System.out.println(Thread.currentThread().getName()+" 吃包子~~~"+i);
            }
            try{
                System.out.println(Thread.currentThread().getName()+" 休眠中~~~");
                Thread.sleep(5000);
            }catch (InterruptedException ex){
                //当线程执行到一个interrupt方法,就会catch一个异常,可以加入自己的业务代码
                //InterruptedException 捕获到一个中断异常
                System.out.println(Thread.currentThread().getName()+" 被interrupt了");
            }
        }
    }
}

线程插队

在这里插入图片描述

package com.hspdu.thread;

public class ThreadYield {
    public static void main(String[] args)throws Exception {
        ThreadT t = new ThreadT();
        t.start();
        int count = 0;
        boolean flag = true;
        while(flag){
            if (count==5){
                t.join();//加入
                Thread.yield();//礼让,不一定成功
            }
            if(count==20){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"输出了 "+(++count)+"次");
        }

    }
}
class ThreadT extends Thread{
    @Override
    public void run() {
        int count = 0;
        boolean flag = true;
        while(flag){
            if(count==20){
                break;
            }
            System.out.println("沙鹰-天神"+Thread.currentThread().getName()+"输出了 "+(++count)+"次");
        }
    }
}

守护线程

在这里插入图片描述
在这里插入图片描述

package com.hspdu.thread;

public class ThreadShouHu {
    public static void main(String[] args) throws Exception {
        MyShouHuThread shou = new MyShouHuThread();
        //如果我们希望主线程结束时子线程也结束
        //只需将子线程设为守护线程即可
        shou.setDaemon(true);//设置为守护线程
        shou.start();
        for (int i=0;i<=10;i++){
            System.out.println("主线程执行中");
            Thread.sleep(1000);
        }
    }
}
class MyShouHuThread extends Thread{
    @Override
    public void run() {
        for (;;){//无限循环
            try{
                Thread.sleep(1000);
            }catch (Exception ex){
                ex.printStackTrace();
            }
            System.out.println("MyShouHuThread线程执行中");
        }
    }
}

线程七大状态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

线程同步

线程同步通过关键字:synchronized实现
在方法上添加该关键字,此时方法变为同步方法,同步方法的概念是锁,线程必须单独执行。
在这里插入图片描述
在这里插入图片描述

在先前售票程序中,窗口会出现超额出售票的情况,此时将run()方法的代码写到一个同步方法中,再调用,就可以避免出现超额出售票的情况。

互斥锁

同步方法的原理是给对象添加一把锁,线程们会去抢这把锁,具体是哪个线程拿到锁是不确定的,非公平锁。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

线程死锁

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

释放锁

在这里插入图片描述
在这里插入图片描述

线程练习

598

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

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

相关文章

如何炼就数据分析的思维?

目录 前言结构化思维假说演绎思维指标化思维维度分析思维 前言 面对数据异常&#xff0c;我们经常会出现“好像是A原因引起的&#xff1f;”“貌似和B原因也相关&#xff1f;““有可能是 C操作不当“的主观臆测。 或者&#xff0c;拿到一个分析议题&#xff0c;分析”11 月销售…

@ConfigurationProperties注解使用方法(内含源代码)

ConfigurationProperties注解使用方法&#xff08;内含源代码&#xff09; 源代码下载链接地址&#xff1a;https://download.csdn.net/download/weixin_46411355/87400774 目录ConfigurationProperties注解使用方法&#xff08;内含源代码&#xff09;源代码下载链接地址&…

怎么识别截图中的文字?这三个方法让你轻松学会

在日常工作或学习中&#xff0c;我们会经常在网上查阅一些资料&#xff0c;当遇到一些优美的句子或者段落时&#xff0c;都会手动摘抄下来&#xff0c;这种记录方式不仅很耗时&#xff0c;还耗费精力&#xff0c;并且现在很多网站都已经不支持文本复制了&#xff0c;遇到这种情…

6.验证面试高频问题整理(附答案)

目录 Q126.top-down phase、bottom-up phase有哪些 Q127.为什么build_phase是top-down phase&#xff0c;connect_phase是bottom-up phase Q128.$size用于packed array和unpacked array分别得到的什么 Q129.class和struct的异同 Q130.class和module的异同 Q131.对象创建的…

MAC系统 LightGBM模型转为pmml格式

一、配置JAVA环境和Maven环境 参考以下两个博客即可 MAC 系统安装 JDK 及环境变量配置_蜗牛的博客-CSDN博客_mac jdk环境变量配置 MAC 系统安装 Maven 及环境变量配置_蜗牛的博客-CSDN博客_mac安装mpv 二、下载JPMML-LightGBM 先在Git上下载 直接下载或使用git clone http…

Aop切面编程原理和Spring实现

Aop切面编程概念 AOP切面编程一般可以帮助我们在不修改现有代码的情况下,对程序的功能进行拓展,往往用于实现 日志处理,权限控制,性能检测,事务控制等 AOP实现的原理就是动态代理,在有接口的情况下,使用JDK动态代理,在没有接口的情况下使用cglib动态代理 为Dao层所有的add方法…

字体反爬,一种来自字体设计师的跨行反爬案例 | 案例 28

本篇博客涉及的内容非常有价值&#xff0c;尤其是在反爬领域。 核心内容为自定义字体文件反爬。 文章目录准备工作在 Web 页面中使用字体文件整理文字编码Flask 中随机一串数字&#xff0c;渲染到前台总结准备工作 在正式编写代码前&#xff0c;需要先安装 FontCreator &#…

GeoServer学习笔记-01GeoSever运行编译

一、运行1. 下载GeoServerGitHub仓库地址&#xff1a;https://github.com/geoserver/geoserver2.本地代码工具打开项目在idea里&#xff0c;文件->新建->来自现有的源代码项目&#xff0c;选择项目的pom文件加载项目。3.idea编译环境设置&#xff08;1&#xff09;设置jd…

图论(5)最小生成树简单应用

活动 - AcWing 参考&#xff1a;《算法竞赛进阶指南》-lyd 目录 一、基础算法 二、 1.最短网络&#xff08;prim板子&#xff09; 2.局域网&#xff08;kruskal板子&#xff09; 3.繁忙的都市 4.1143. 联络员 5.连接格点&#xff08;预处理&#xff09; 一、基础算法…

影响电商发展的重要因素及电商未来的发展可能

易观分析&#xff1a;自从互联网传入中国以后&#xff0c;特别是2000年以后&#xff0c;一直保持着非常快的演变速度&#xff0c;而以互联网为基础的电商则更是发展成了中国互联网的代表性行业。中国电商的发展不仅在初期有着非常高的增速&#xff0c;有着多样化的演进路线&…

Numpy(3)—切片和索引、高级索引、Broadcast、迭代数组、广播迭代

1.切片和索引 eg1&#xff1a;我们首先通过 arange() 函数创建 ndarray对象。 然后&#xff0c;分别设置起始&#xff0c;终止和步长的参数为 2&#xff0c;7 和 2。 import numpy as npa np.arange(10) s slice(2, 7, 2) # 从索引 2 开始到索引 7 停止&#xff0c;间隔为…

【笔记】行人属性识别

【论文】https://arxiv.org/pdf/1901.07474.pdf &#xff08;以下序号与论文序列不对应&#xff09; 属性可以看作是高层语义信息&#xff0c;对视点变化和观察条件多样性具有更强的鲁棒性 本文试图解决以下几个重要问题: (1)传统和基于深度学习的行人属性识别算法之间的联系…

Java_Git:4. 分支管理

目录 1 创建合并分支 2 使用TortoiseGit实现分支管理 2.1 创建分支 2.2 合并分支 3 解决冲突 1 创建合并分支 Git会把每次的提交&#xff0c;串成一条时间线&#xff0c;即一个分支。 初始状态&#xff0c;Git只有一条时间线&#xff08;分支&#xff09;&#xff0c;这个分…

高级Spring之BeanFactory 后处理器

老样子&#xff0c;直接上代码演示&#xff0c;准备一个干净的容器&#xff1a; // ⬇️GenericApplicationContext 是一个【干净】的容器GenericApplicationContext context new GenericApplicationContext();//注册configBeancontext.registerBean("config", Conf…

【C语言学习笔记】39. 错误处理、递归

前言 C 语言不提供对错误处理的直接支持&#xff0c;但是作为一种系统编程语言&#xff0c;它以返回值的形式允许您访问底层数据。 错误处理 C 语言不提供对错误处理的直接支持&#xff0c;但是作为一种系统编程语言&#xff0c;它以返回值的形式允许您访问底层数据。在发生…

振弦采集模块配置工具VMTool的MODBUS 工具模块

振弦采集模块配置工具VMTool的MODBUS 工具模块 &#xff08; 1&#xff09; 寄存器查看 此功能模块提供标准的 MODBUS 协议寄存器显示及单个寄存器修改功能&#xff0c;通过点击扩展功能区的【 MODBUS】 标签切换到此模块&#xff0c;如下图所示。 此模块将 VMXXX 所有寄存器以…

Codeforces Round #847 (Div. 3) A~E

比赛链接&#xff1a;Dashboard - Codeforces Round #847 (Div. 3) - Codeforces 目录 A. Polycarp and the Day of Pi B. Taisia and Dice C. Premutation D. Matryoshkas E. Vlad and a Pair of Numbers A. Polycarp and the Day of Pi 题意&#xff1a;求出一个数字…

一步创建 AI 图像网站,即刻生成 AI 图像解决方案 #Graydient

过去一年当中&#xff0c;AI 画图工具非常火爆&#xff0c;一条简单的指令&#xff0c;就能快速得出超高品质的图形&#xff0c;这对于游戏开发者来说无疑是令人振奋的消息&#xff0c;尤其是没有预算和人手打造美术资源的中小团队。从网络上看到的结果来看&#xff0c;AI 的绘…

JDBC(powernode 文档)(内含源代码)

源代码下载地址链接&#xff1a;https://download.csdn.net/download/weixin_46411355/87400304 目录 JDBC概述 1.1 前言 1.2 什么是JDBC 1.3 JDBC的原理 1.4 程序员&#xff0c;JDBC&#xff0c;JDBC驱动的关系及说明 1.4.1 JDBC API 1.4.2 JDBC 驱动 1.4.3 Java程序员…

并发编程-多线程并发设计原理

并发编程-多线程&并发设计原理并发编程简介多线程&并发设计原理1 多线程回顾1.1 Thread和Runnable1.1.1 Java中的线程1.1.2 Java中的线程&#xff1a;特征和状态1.1.3 Thread和Runnable接口1.1.4 Callable1.2 synchronized关键字1.2.1 锁的对象1.2.2 锁的本质1.2.3 实现…