【JavaSE线程知识总结】

news2024/11/17 11:54:20

多线程

  • 一.创建线程
    • 1.多线程创建方式一(Thread)
    • 2.多线程创键方式二(Runnable)
    • 3.线程创建方式三
  • 二.线程安全问题
    • 解决办法
      • 1.使用同步代码块synchornized
    • 2 .使用Lock解决线程安全问题
  • 三.总结

  • 线程就是程序内部的一条执行流程

一.创建线程

常用的方法

  • Thread.currentThread(): 获取当前线程
  • Thread.getName(): 获取当前线程的名称
  • Thread.setName(): 设置当前线程的名称
  • Thread.yield(): 礼让当前正在执行的线程
  • Thread.sleep(long millis): 让当前线程暂停millis毫秒
  • Thread.interrupt(): 中断当前线程
  • Thread.isInterrupted(): 判断当前线程是否被中断
  • Thread.currentThread().interrupt(): 中断当前线程
  • Thread.join(): 插队,调用这个方法的线程先执行完毕
  • Thread.sleep()睡眠

1.多线程创建方式一(Thread)

  • 定义一个子类MyThread继承Thread,重写run方法
  • 创建Mythread类的对象
  • 通过对象调用start方法启动线程,线程开启后,会自动调用线程对象的run方法执行
  • JVM会自动开启一个线程,执行main方法,称为主线程
  • 主线程中开启了其他线程称为子线程
  • 开启了子线程后,子线程会跟我们的主线程争抢资源,谁抢到了谁就先执行,执行一小会用释放,再重新抢占资源
    优点: 创建线程简单
    缺点: 扩展性不强,不能返回线程执行结果
    在这里插入图片描述
    在这里插入图片描述

2.多线程创键方式二(Runnable)

  • 定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法
  • 创建MyRunnable任务对象
  • 把MyRunnable对象交给Thread处理
  • 调用start()方法启动线程

优点
线程任务与线程对象分离,可以让同一线程执行不同的任务
缺点
需要多一个Runnable对象
不能返回线程结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.线程创建方式三

  • 实现callable<返回值类型>接口,重写call方法
  • callable接口在实现的时候需要指定泛型,用来确定返回值的数据类型
  • 创建FutureTask对象,构造方法中需要传入callable接口实现类对象
  • FutureTask()中提供了一个get(),它是一个阻塞的方法,他会阻塞线程一直从Futurue对象中去获取返回的结果,如果没有获取到会一致阻塞等待
  • 创建Thread对象,构造方法中传入futureTask对象
  • 调用start()方法启动线程
  • 调用get()方法的时候会有异常(最好分开进行try… catch异常捕获,因为当有一条线程出现异常的时候,不会影响到其他线程的返回结果,)
package com.dream.Thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class ThreadDemo03 {
    public static void main(String[] args) {
        //1.线程创建的方式三: 实现callable接口,重写call方法
        //callable接口在实现的时候需要指定泛型,用来确定返回值的数据类型
        //2.创建callable接口实现类的对象
        MyThread3 myThread3 = new MyThread3(100);
        //3.创建FutureTask对象,构造方法中需要传入callable接口实现类对象
        FutureTask<String> futureTask = new FutureTask<>(myThread3);
        //futureTask对象是线程任务对象,他的get方法可以在线程运行结束后,获取线程执行结果
        //4.创建Thread对象,构造方法中传入futureTask对象
        Thread t = new Thread(futureTask);
        //5.启动线程
        t.start();


        MyThread3 myThread3_2 = new MyThread3(200);
        FutureTask<String> futureTask_2 = new FutureTask<>(myThread3_2);
        Thread t2 = new Thread(futureTask_2);
        t2.start();


        //6.获取线程执行结果(最好分开进行try... catch异常捕获,因为当有一条线程出现异常的时候,不会影响到其他线程的返回结果,)
        try {
            String result = futureTask.get();
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            String result_2 = futureTask_2.get();
            System.out.println(result_2);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}


class MyThread3 implements Callable<String> {
    private int n;

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

    @Override
    public String call() throws Exception {
        //计算1-n的和返回
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            sum += i;
        }
        return "1-" + n + "的和为:" + sum;
    }
}

二.线程安全问题

  • 存在多个线程在同时执行
  • 同时访问一个共享资源
  • 同时对共享资源做操作

比如两个人访问同一个银行账户,就会出现线程安全问题

package com.dream.threadsafe;

public class MyRunnable implements Runnable {
    private Account account = new Account();

    @Override
    public void run() {

        if (account.getBalance() >= 100000) {
            account.withdraw(account, 100000);
        } else {
            System.out.println("余额不足,取款失败");
        }
        
    }
}

/**
 * 模拟取款
 */

class Account {
    private int balance = 100000;// 余额

    public int getBalance() {
        return balance;
    }

    public void withdraw(Account acc, int amount) {
        System.out.println(Thread.currentThread().getName() + "正在取款" + amount);
        balance -= amount;
        System.out.println(Thread.currentThread().getName() + "取款成功,余额为" + balance);
    }
}

启动线程

public class Test {
    public static void main(String[] args) {
        MyRunnable mr = new MyRunnable();
        Thread t1 = new Thread(mr, "小明");
        Thread t2 = new Thread(mr, "小红");
        t1.start();
        t2.start();
    }
}

解决办法

1.使用同步代码块synchornized

  • 同步锁:我们传入的参数要是唯一的对象,
  • 但是不要直接使用字符串作为锁对象,因为会导致其它无关线程不能同步线程
  • 如果同步锁对象是在实例方法内部,那么锁对象就是this
  • 每次抢占到资源都会判断当前锁是否是开启的,开启了就进入执行,关闭则等待
  • 如果同步锁对象是在静态方法内部,那么锁对象就是 类名.class
  • 也可以直接加在方法的修饰符后面,构成同步方法
    在这里插入图片描述
    在这里插入图片描述

2 .使用Lock解决线程安全问题

  • Lock是一个接口,需要创建它的实现类对象ReentranLock()是Lock接口的实现类
  • 相较于synchronized锁,Lock会更加的灵活
  • 他俩都属于重量级锁
private final Lock lk = new ReentrantLock();
public void withdraw(Account acc, double money) {
        lk.lock();//上锁
        try {
            if (this.money >= money) {
                //余额足够,取款
                System.out.println(Thread.currentThread().getName() + "取款成功");
                //更新余额
                this.money -= money; //
                System.out.println(acc.getCardId() + "余额为:" + this.money);
            } else {
                System.out.println("余额不足");
                System.out.println(Thread.currentThread().getName() + "取款失败");
            }
        } finally {
            lk.unlock();//解锁
        }

    }

三.总结

本章主要讲解了线程几种线程的创建方式,线程安全问题出现的场景,以及线程安全的解决方式

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

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

相关文章

Leetcode - 周赛423

目录 一&#xff0c;3349. 检测相邻递增子数组 I 二&#xff0c;3350. 检测相邻递增子数组 II 三&#xff0c;3351. 好子序列的元素之和 四&#xff0c;3352. 统计小于 N 的 K 可约简整数 一&#xff0c;3349. 检测相邻递增子数组 I 本题有两种做法&#xff1a; 先求出递增…

boost之property

简介 property在boost.graph中有使用&#xff0c;用于表示点属性或者边属性 结构 #mermaid-svg-56YI0wFLPH0wixrJ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-56YI0wFLPH0wixrJ .error-icon{fill:#552222;}#me…

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-25

文件下载与邀请翻译者 学习英特尔开发手册&#xff0c;最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册&#xff0c;会是一件耗时费力的工作。如果有愿意和我一起来做这件事的&#xff0c;那么&#xff…

paddle表格识别数据制作

数据格式 其中主要数据有两个一个表格结构的检测框&#xff0c;一个是tokens&#xff0c;注意的地方是 1、只能使用双引号&#xff0c;单引号不行 2、使用带引号的地方是tokens里面 "<tr>", "<td", " colspan2", ">",&quo…

Java 全栈知识体系

包含: Java 基础, Java 部分源码, JVM, Spring, Spring Boot, Spring Cloud, 数据库原理, MySQL, ElasticSearch, MongoDB, Docker, k8s, CI&CD, Linux, DevOps, 分布式, 中间件, 开发工具, Git, IDE, 源码阅读&#xff0c;读书笔记, 开源项目...

WebRTC视频 04 - 视频采集类 VideoCaptureDS 中篇

WebRTC视频 01 - 视频采集整体架构 WebRTC视频 02 - 视频采集类 VideoCaptureModule WebRTC视频 03 - 视频采集类 VideoCaptureDS 上篇 WebRTC视频 04 - 视频采集类 VideoCaptureDS 中篇&#xff08;本文&#xff09; WebRTC视频 05 - 视频采集类 VideoCaptureDS 下篇 一、前言…

任务调度中心-XXL-JOB使用详解

目录 详解 调度中心 执行器 原理 快速入门 源码仓库地址 1.初始化数据库 2.配置调度中心 1.解压源码 2.需改配置文件 3.启动调度中心 3.配置执行器 1.引入pom依赖 2.修改配置文件 3.执行器组件配置 4.部署执行器项目 4.开发第一个任务 BEAN模式&#xff08;类…

如何搭建一台邮箱服务器,配置满分邮箱

如何搭建一台邮箱服务器,配置满分邮箱 搭建一台个人邮箱服务器听上去非常有技术含量&#xff0c;但只要准备工作充分&#xff0c;并且选择合适的软件&#xff0c;配置满分的邮箱&#xff0c;其实并没有想象中那么困难。在这篇文章中&#xff0c;我们将介绍搭建邮箱服务器的 必备…

C# unity 星期几 年月日控制

参考微软的datetime文档 正常输出是中文的周几&#xff0c;需要中文的星期几可以通过英文转中文实现 实现效果如图所示&#xff1a; 代码如下&#xff1a; public class TimeControl : MonoBehaviour{public TextMeshProUGUI TimeText01;public TextMeshProUGUI TimeText02…

linux病毒编写+vim shell编程

学习视频来自B站UP主泷羽sec&#xff0c;如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 请一定遵循《网络空间安全法》&#xff01;&#xff01;&#xff01; Linux目录介绍 /bin 二进制可执行文件&#xff08;kali里面是工具一些文件&#xff09;/etc 系统的管理和配置文…

C语言和C++的常量概念与区别分析

文章目录 &#x1f4af;前言&#x1f4af;常量的概念和作用&#x1f4af;C语言中 const 的应用与限制#define 和 enum 的使用方法 &#x1f4af;C 中 const 的计算方法和处理&#x1f4af;代码实例和应用区别&#x1f4af;C 和 C 的常量兼容性问题和负载&#x1f4af;分析 C 和…

PCHMI串口接收实验

插入的唯一一行代码 config1.START((Control)this, System.Reflection.Assembly.GetExecutingAssembly().GetTypes(), null);

【链路层】空口数据包详解(4):数据物理通道协议数据单元(PDU)

目录 一、概述 1.1. 头部&#xff08;Header&#xff09;结构 1.2. MIC字段的情况说明 1.3. 有效载荷&#xff08;Payload&#xff09;格式与LLID字段的关联 二、LL Data PDU 2.1. 定义与用途 2.2. 头部字段设置 2.3. 空PDU&#xff08;Empty PDU &#xff09; 2.4. 数…

动态规划子数组系列(二) 环形子数组的最大和

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public int maxSubarraySumCircular(int[] nums) {int sum 0;int n nums.length;int[] f new int[n1];int[] g new int[n1];int ret 0, fmax -0x3f3f3f3f, gmin Integer.MAX_VALUE;for(int i 1; i < n; i)…

网络工程师教程第6版(2024年最新版)

网络工程师教程(第6版)由清华大学出版社出版,由工业和信息化部教育与考试中心组编,张永刚、王涛、高振江任主编,具体介绍如下。 相关信息: 出版社: 清华大学出版社 ISBN:9787302669197 内容简介: 本书是工业和信息化部教育与考试中心组织编写的考试用书。本书 根据…

数据结构C语言描述3(图文结合)--双链表、循环链表、约瑟夫环问题

前言 这个专栏将会用纯C实现常用的数据结构和简单的算法&#xff1b;有C基础即可跟着学习&#xff0c;代码均可运行&#xff1b;准备考研的也可跟着写&#xff0c;个人感觉&#xff0c;如果时间充裕&#xff0c;手写一遍比看书、刷题管用很多&#xff0c;这也是本人采用纯C语言…

7.高可用集群架构Keepalived双主热备原理

一. 高可用集群架构Keepalived双主热备原理 (1)主机+备机keepalived配置(192.168.1.171) ! Configuration File for keepalivedglobal_defs {# 路由id:当前安装keepalived节点主机的标识符,全局唯一router_id keep_101 } #计算机节点(主机配置) vrrp_instance VI_1 {</

深入理解接口测试:实用指南与最佳实践5.0(二)

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

TypeScript简介:TypeScript是JavaScript的一个超集

官方描述&#xff1a;TypeScript 是 JavaScript 的一个超集 GitHub官网&#xff1a;https://github.com/Microsoft/TypeScript TypeScript is a superset of JavaScript that compiles to clean JavaScript output. TypeScript 是 JavaScript 的一个超集&#xff0c;支持 EC…

【计算机网络】UDP网络程序

一、服务端 1.udpServer.hpp 此文件负责实现一个udp服务器 #pragma once#include <iostream> #include <string> #include <cstdlib> #include <cstring> #include <functional> #include <strings.h> #include <unistd.h> #incl…