Java中的线程

news2025/1/18 11:00:36

线程

什么是线程:

image-20221117184424814

image-20221117184429961

什么是多线程:

image-20221117184455661

学习目的:

image-20221117184751362

多线程的创建

方式一:继承Thread类

image-20221117185309899

public class MyThread{
    public static void main(String[] args) {
        Thread thread01 = new Thread01();
        thread01.start();
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程执行输出:"+i);
        }
    }
}

class Thread01 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程执行输出:"+i);
        }
    }
}

image-20221117185920965

image-20221117190049789

注意:

如果用thread01.run()而不用thread01.start(),那么将还是单线程执行。

主线程任务不要放在子线程之前,否则还是单线程的情形。

方式二:实现Runnable

方式二相对于方式一来说线程类可以继承别的类。

image-20221117190714908

public class MyThread{
    public static void main(String[] args) {
        Runnable r = new MyRunnable();
        // r为任务对象,要交给一个线程对象去处理。
        Thread thread = new Thread(r);
        thread.start();
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程输出:"+i);
        }
    }
}

class MyRunnable implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程输出:"+i);
        }
    }
}

image-20221117191621000

image-20221117191835605

public class MyThread{
    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println("子线程输出:"+i);
                }
            }
        };
        // r为任务对象,要交给一个线程对象去处理。
        Thread thread = new Thread(r);
        thread.start();
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程输出:"+i);
        }
    }
}

方式三:jdk5.0新增,实现Callable接口

image-20221117194327720

image-20221117194636585

public class ThreadDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建callable任务对象
        Callable<String> c = new MyCallable(100);
        // 把callable任务对象交给FutureTask对象:是Runnable对象(实现了Runnable接口),可以交给Thread
        // FutureTask对象可以使用get方法得到线程返回的结果
        FutureTask<String> f = new FutureTask<>(c);
        Thread t = new Thread();
        t.start();
        // 如果f任务没有执行完毕,则f.get()会等待,线程跑完才提取结果
        System.out.println(f.get());
    }
}
class MyCallable implements Callable<String>{
    private int n;

    public MyCallable(int n) {
        this.n = n;
    }

    @Override
    public String call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            sum = sum + i;
        }
        return "子线程的结果为:"+sum;
    }
}

image-20221117210743828

image-20221117210820249

三种方式的对比

image-20221117210847107

Thread的常用方法

自定义线程名字1:

public class ThreadDemo {
    public static void main(String[] args) {
        Thread t1 = new MyThread();
        t1.setName("1号");
        t1.start();

        Thread t2 = new MyThread();
        t2.setName("2号");
        t2.start();

        // 哪个线程执行它,他就返回哪个线程(当前线程对象)。
        Thread ct = Thread.currentThread();
        // 主线程调用它,拿到主线程的名字(main)。
        String s = ct.getName();
        for (int i = 0; i < 4; i++) {
            System.out.println(s+"线程输出"+i);
        }
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 4; i++) {
            System.out.println(Thread.currentThread().getName()+"线程输出"+i);
        }
    }
}

自定义线程名字2:

public class ThreadDemo {
    public static void main(String[] args) {
        Thread t1 = new MyThread("1号");
        t1.start();

        Thread t2 = new MyThread("2号");
        t2.start();

        // 哪个线程执行它,他就返回哪个线程(当前线程对象)。
        Thread ct = Thread.currentThread();
        // 主线程调用它,拿到主线程的名字(main)。
        String s = ct.getName();
        for (int i = 0; i < 4; i++) {
            System.out.println(s+"线程输出"+i);
        }
    }
}
class MyThread extends Thread {
    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 4; i++) {
            System.out.println(Thread.currentThread().getName()+"线程输出"+i);
        }
    }
}

线程的休眠方法:

image-20221117212849038

image-20221117213446136

image-20221117213618193

线程安全

image-20221119095621485

public class MyThread  {
    public static void main(String[] args) {
        Account account = new Account("houyiming",100000);
        new DrawThread(account,"小明").start();
        new DrawThread(account,"小红").start();
    }
}

public class DrawThread extends Thread {
    private Account acc;

    public DrawThread(Account acc,String name){
        super(name);
        this.acc = acc;
    }

    @Override
    public void run() {
        acc.drawMoney(100000);
    }
}

public class Account {
    private String CardId;
    private int money;

    public Account(String cardId, int money) {
        CardId = cardId;
        this.money = money;
    }

    public Account() {
    }

    public String getCardId() {
        return CardId;
    }

    public void setCardId(String cardId) {
        CardId = cardId;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
    public void drawMoney(int money){
        String s = Thread.currentThread().getName();
        if (this.money >= money){
            System.out.println(s+"取钱,吐出:"+money);
            this.money -= money;
            System.out.println(s+"取钱后剩余:"+this.money);
        }else{
            System.out.println(s+":余额不足 ");
        }
    }
}

线程同步

image-20221119102737039

同步代码块

image-20221119102856804

synchronized ("houyiming") { // 锁对象任意,但是要唯一。
    if (this.money >= money){
        System.out.println(s+"取钱,吐出:"+money);
        this.money -= money;
        System.out.println(s+"取钱后剩余:"+this.money);
    }else{
        System.out.println(s+":余额不足 ");
    }
}

image-20221119103754723

synchronized (this) {
    if (this.money >= money){
        System.out.println(s+"取钱,吐出:"+money);
        this.money -= money;
        System.out.println(s+"取钱后剩余:"+this.money);
    }else{
        System.out.println(s+":余额不足 ");
    }
}

同步方法

image-20221119104103874

public synchronized void drawMoney(int money){
    String s = Thread.currentThread().getName();
    if (this.money >= money){
        System.out.println(s+"取钱,吐出:"+money);
        this.money -= money;
        System.out.println(s+"取钱后剩余:"+this.money);
    }else{
        System.out.println(s+":余额不足 ");
    }
}

image-20221119104428659

Lock锁

image-20221119105424142

private final Lock lock = new ReentrantLock();
    public void drawMoney(int money){
        String s = Thread.currentThread().getName();
        lock.lock();
        try {
            if (this.money >= money){
                System.out.println(s+"取钱,吐出:"+money);
                this.money -= money;
                System.out.println(s+"取钱后剩余:"+this.money);
            }else{
                System.out.println(s+":余额不足 ");
            }
        } finally {
            lock.unlock();
        }
    }

线程通信

image-20221119113015779

image-20221119113645553

image-20221119151745191

线程池[重点]

image-20221119152249597

线程池实现的API、参数说明

image-20221119153032458

方式一:

image-20221119153131164

image-20221119153751331

线程池实现Runnable接口

image-20221119154045189

public class ThreadPoolDemo {
    public static void main(String[] args) {
        // 创建线程池对象
        ExecutorService pool = new ThreadPoolExecutor(3,5,6, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
        // 把任务交给线程池处理
        Runnable r = new MyRunnable();
        pool.execute(r);
        pool.execute(r);
        pool.execute(r);

        pool.execute(r);
        pool.execute(r);
        pool.execute(r);
        pool.execute(r);
        pool.execute(r);

        // 关闭线程池,即使任务没有完成,会丢失任务
        pool.shutdownNow();
        // 等所有任务完成之后关闭
        pool.shutdown();
    }
}
public class MyRunnable implements Runnable {
    @Override
    public void run() {

        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+": hello world : "+i);
            try {
                Thread.sleep(100000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

image-20221119165553873

线程池实现Callable任务

public class ThreadPoolDemo2 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建线程池对象
        ExecutorService pool = new ThreadPoolExecutor(3,5,6, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
        // 把任务交给线程池处理
        Future<String> f1 = pool.submit(new MyCallable(100));
        Future<String> f2 = pool.submit(new MyCallable(200));
        Future<String> f3 = pool.submit(new MyCallable(300));
        Future<String> f4 = pool.submit(new MyCallable(400));
        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());
    }
}

public class MyCallable implements Callable<String> {
    private int n;
    public MyCallable(int n){
        this.n = n;
    }
    public MyCallable(){
    }
    @Override
    public String call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            sum += i;
        }
        return Thread.currentThread().getName()+"执行"+1+"到"+n+"的结果为:"+sum;
    }
}

Executors工具类实现线程池

image-20221119192541768

ExecutorService pool = Executors.newFixedThreadPool(3);

image-20221119194547796

定时器

image-20221119195359305

Timer定时器

image-20221119200635717

public class TimerDemo1 {
    public static void main(String[] args) {
        Timer timer = new Timer(); // 定时器本身就是一个线程
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"执行一次");
            }
        },3000,2000);
    }
}

ScheduledExecutorService定时器

image-20221119200803003

public class TimerDemo1 {
    public static void main(String[] args) {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"11执行输出");
                try {
                    Thread.sleep(30000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },0,2, TimeUnit.SECONDS);

        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"22执行输出");
            }
        },0,2, TimeUnit.SECONDS);
    }
}

并发并行、生命周期

image-20221119204009237

image-20221119204910192
image-20221119204921360

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

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

相关文章

翻倍增长!C-V2X商业化“提速”,新一代模组加速“助跑”

C-V2X正在逐步走向商业的规模化部署&#xff0c;由此也带动了C-V2X模组需求的高速增长。 高工智能汽车研究院监测数据显示&#xff0c;今年1-9月中国市场&#xff08;不含进出口&#xff09;乘用车前装标配搭载V2X技术新车交付上险为10.58万辆&#xff0c;同比增长283.33%&…

计算机视觉|投影与三维视觉

这一篇将学习投影与三维视觉&#xff0c;沿用上一篇 计算机视觉|针孔成像&#xff0c;相机内外参及相机标定&#xff0c;矫正的重要性 摄像机内参数矩阵M、畸变参数、旋转矩阵R、平移向量T以及但影响矩阵H。回顾放射和投影变换&#xff0c;并使用POSIT算法从一幅图像中查找获得…

基于stm32单片机有害气体监测检测Proteus仿真

资料编号&#xff1a;097 下面是相关功能视频演示&#xff1a; 97-基于stm32单片机有害气体监测检测Proteus仿真&#xff08;仿真源码全套资料&#xff09;功能介绍&#xff1a;检测当前的有害气体浓度&#xff0c;LCD1602显示&#xff0c;并且可以自动打开关闭风扇&#xff…

Pulsar 各个Shedder分析及新的Shedder -- AvgShedder

看到今年Pulsar 峰会上挺多人分享负载均衡的内容&#xff0c;这里也整理分享一下相关的内容。 社区现有策略的分析 LoadSheddingStrategy pulsar进行shedding的时候&#xff0c;使用的是ThresholdShedder类&#xff0c;ThresholdShedder类是LoadSheddingStrategy接口的其中一…

锐捷SuperVlan实验配置

Super Vlan配置 创建Vlan vlan range 2,3,4,10,20 配置Vlan10为Super Vlan&#xff0c;Vlan 2,3,4为Sub Vlan vlan 10 supervlan subvlan 2,3,4 配置Sub Vlan的地址范围&#xff08;也可以不配置&#xff09; Vlan 2 subvlan-address-range 192.168.10.10 192.168.10.50 配置S…

【数据结构】—时间复杂度or空间复杂度以及基础题目练习

小菜坤日常上传gitee代码&#xff1a;https://gitee.com/qi-dunyan ❤❤❤ 个人简介&#xff1a;双一流非科班的一名小白&#xff0c;期待与各位大佬一起努力&#xff01; 推荐网站&#xff1a;cplusplus.com 目录前言算法与复杂度时间复杂度大O的渐进表示法时间复杂度计算练习…

[附源码]java毕业设计社区疫情防控管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

MySQL纯代码复习(上)

前言 本文章是用于总结尚硅谷MySQL教学视频的记录文章&#xff0c;主要用于复习&#xff0c;非商用 原视频连接&#xff1a;https://www.bilibili.com/video/BV1iq4y1u7vj/?p21&spm_id_frompageDriver&vd_sourcec4ecde834521bad789baa9ee29af1f6c https://www.bilib…

【设计模式】 - 创建者模式 -建造者模式

1. 建造者模式 1.1 概述 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于&#xff1a;某个对象的构建过程复杂的情况。 由于实现了…

小目标检测:基于切图检测的yolov5小目标检测

目前在目标检测方面有着众多的检测框架,比如两阶段的FasterRcnn、以及yolo系列的众多模型。yolo系列在实际中用的最多,一方面性能确实不错,另一方面具有着较多的改进型系列。今天我们主要使用的yolov5系列。具体原理过程就不多说了,大家自行百度。放一张v5的网络结构图。 大…

计算机网络部分(一)

1 请描述 TCP/IP 协议中主机与主机之间通信的三要素 答&#xff1a; IP 地址&#xff08;IP address&#xff09; 子网掩码&#xff08;subnet mask&#xff09; IP 路由&#xff08;IP router&#xff09; 扩展&#xff1a; TCP/IP定义&#xff1a;TCP/IP是基于TCP和IP这两个…

883. 三维形体投影面积

883. 三维形体投影面积 在 n x n 的网格 grid 中&#xff0c;我们放置了一些与 x&#xff0c;y&#xff0c;z 三轴对齐的 1 x 1 x 1 立方体。 每个值 v grid[i][j] 表示 v 个正方体叠放在单元格 (i, j) 上。 现在&#xff0c;我们查看这些立方体在 xy 、yz 和 zx 平面上的投…

【Java八股文总结】之Java设计模式

文章目录Java设计模式一、设计模式概述1、什么是设计模式&#xff1f;2、设计模式的6大原则3、具体的设计模式1、单例模式Q&#xff1a;为什么使用两个 if (singleton null) 进行判断&#xff1f;Q&#xff1a;volatile 关键字的作用&#xff1f;2、原型模式补充&#xff1a;浅…

yml中无法解析类 ‘HikariDataSource‘

目录 yml中无法解析类 HikariDataSource ⭐关于HikariDataSource的信息 yml中无法解析类 HikariDataSource 修改之前该行是报红的 具体代码 # 配置项目信息 spring:profiles:active: prod # yml中配置文件的环境配置&#xff0c;dev&#xff1a;开发环境&#xff0c;t…

06_通信过程

知识点1【通信过程概述】 2、PC和集线器Hub 2、PC机和交换机switch 2、路由器&#xff08;重要哟&#xff09; 知识点1【通信过程概述】 1、PacketTracer5.exe 安装 一路next 2、PC和集线器Hub 选择集线器 选择主机&#xff1a; 选择线 一个集线器4台主机&#xff1a; 配…

ZooKeeper教程

官网&#xff1a;Apache ZooKeeper 什么是Zookeeper&#xff1f; ZooKeeper是一个集中服务&#xff0c;用于维护配置信息、命名、提供分布式同步和组服务。所有这些类型的服务都以某种形式被分布式应用程序使用。每次实施它们时&#xff0c;都要进行大量的工作来修复不可避免的…

Flink水位线-详细说明

文章目录时间语义Flink 中的时间语义?哪种时间语义更重要?1. 水位线&#xff08;Watermark&#xff09;1.1 什么是水位线?1.2 如何生成水位线?1.3 水位线的传递1.4 水位线的计算&#x1f48e;&#x1f48e;&#x1f48e;&#x1f48e;&#x1f48e; 更多资源链接&#xff0…

C#编程流程控制与集合类型

目录 选择语句 if-else语句 switch语句 集合一览 数组 列表 字典 迭代 for循环 foreach循环 while循环 超越无限 总结 本文主要来自<<C#实践入门>>哈里森.费隆 著&#xff0c;仅用为做笔记。 本章将专注以下主题: 选择语句。使用数组(Array)、字典(…

高级UI——Path测量

前言 在Path在UI体系当中不论是在自定义View还是动画&#xff0c;都占有举足轻重的地位。绘制Path&#xff0c;可以通过Android提供的API&#xff0c;或者是贝塞尔曲线、数学函数、图形组合等等方式&#xff0c;而要获取Path上每一个构成点的坐标&#xff0c;一般需要知道Path…

力扣刷题记录120.1-----718. 最长重复子数组

目录一、题目二、代码三、运行结果一、题目 二、代码 class Solution { public://dp[i][j]表示以 i j为末尾 最长公共子序列int findLength(vector<int>& nums1, vector<int>& nums2) {int i,j;int return_int0;vector<vector<int>> dp(n…