多线程(二)

Java多线程--创建多线程的基本方式二:实现Runnable接口 阅读详情

线程安全

程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

我们通过一个案例,演示线程的安全问题:

电影院要卖票,我们模拟电影院的卖票过程。假设要播放的电影是 “哪吒”,本次电影的座位共100个(本场电影只能卖100张票)。

我们来模拟电影院的售票窗口,实现多个窗口同时卖 “哪吒”这场电影票(多个窗口一起卖这100张票)

需要窗口,采用线程对象来模拟;需要票,Runnable接口子类来模拟

测试类

public class ThreadDemo {

    public static void main(String[] args) {

        //创建票对象

        Ticket ticket = new Ticket();

       

        //创建3个窗口

        Thread t1  = new Thread(ticket, "窗口1");

        Thread t2  = new Thread(ticket, "窗口2");

        Thread t3  = new Thread(ticket, "窗口3");

       

        t1.start();

        t2.start();

        t3.start();

    }

}

模拟票

public class Ticket implements Runnable {

    //共100票

    int ticket = 100;

 

    @Override

    public void run() {

        //模拟卖票

        while(true){

            if (ticket > 0) {

                //模拟选坐的操作

                try {

                    Thread.sleep(1);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

                System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);

            }

        }

    }

 

运行结果发现:上面程序出现了问题

  1. 票出现了重复的票
  2. 错误的票 0、-1

 

其实,线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

 线程同步

线程同步的方式有两种:

  1. 方式1:同步代码块
  2. 方式2:同步方法

同步代码块

同步代码块: 在代码块声明上 加上synchronized

synchronized (锁对象) {

    可能会产生线程安全问题的代码

}

同步代码块中的锁对象可以是任意的对象;但多个线程时,要使用同一个锁对象才能够保证线程安全。

使用同步代码块,对电影院卖票案例中Ticket类进行如下代码修改:

public class Ticket implements Runnable {

    //共100票

    int ticket = 100;

    //定义锁对象

    Object lock = new Object();

    @Override

    public void run() {

        //模拟卖票

        while(true){

            //同步代码块

            synchronized (lock){

                if (ticket > 0) {

                    //模拟电影选坐的操作

                    try {

                        Thread.sleep(10);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                    System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);

                }

            }

        }

    }

}

 

同步方法

同步方法:在方法声明上加上synchronized

public synchronized void method(){

   可能会产生线程安全问题的代码

}

 

 同步方法中的锁对象是 this

使用同步方法,对电影院卖票案例中Ticket类进行如下代码修改:

public class Ticket implements Runnable {

    //共100票

    int ticket = 100;

    //定义锁对象

    Object lock = new Object();

    @Override

    public void run() {

        //模拟卖票

        while(true){

            //同步方法

            method();

        }

    }

 

//同步方法,锁对象this

    public synchronized void method(){

        if (ticket > 0) {

            //模拟选坐的操作

            try {

                Thread.sleep(10);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);

        }

    }

}

 

静态同步方法: 在方法声明上加上static synchronized

public static synchronized void method(){

可能会产生线程安全问题的代码

}

 静态同步方法中的锁对象是 类名.class

 

死锁

当线程任务中出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步。这时容易引发一种现象:程序出现无限等待,这种现象我们称为死锁

 

synchronzied(A锁){

    synchronized(B锁){

        

}

}

 

 

·

 

通过HTTP的方式克隆GitHub上的项目 通过HTTP的方式克隆GitHub上的项目 打开想要下载的项目的网页链接,点击Clone or download绿色的按钮,进行如下步骤实现通过HTP的方式下载项目。 点击红色框圈出的位置: 打开想要存放项目的文件夹,在空白处点击鼠标右键,选择Git Bash Here,打开命令行。 输入git clone 复制的下载地址,回车进行下载。 4.正在下载的界面 5.下载完成。 技多不压身 哦耶✌✌✌ ... 阅读详情

相关推荐

金蝶云星空API实战:从零到一,用Postman打通业务数据流

本文详细介绍了如何使用Postman调试金蝶云星空API,从创建第三方应用到实战调试技巧,帮助开发者快速打通业务数据流。文章重点讲解了API配置的关键细节、常见问题排查方法以及自动化测试方案,提升开发效率与准确性。

weixin_33712987的博客 520

【Java从入门到放弃 之 多线程 二】

我们上一篇引入的案例与这一篇引入的案例实际上代表多线程的两个大问题。竞态条件内存可见性另外,使用多线程也不是银弹。使用多线程有优点也有缺点,我们要分析我们遇到的问题 ,分情况使用。之所以使用多线程,实际上是因为CPU运行速度比IO速度快很多,当处理IO的时候,CPU空闲了下来。这个时候我们通过使用多线程技术,就可以多利用CPU空闲时间。但是使用多线程也是有开销的,创建多线程,操作系统会为每一个线程创建必要的数据结构,栈,程序计数器等资源,另外线程切换调度也是需要消耗资源的,这个过程称之为上下文切换。

Snow的博客 1098

果蔬及菜品识别系统

果蔬及菜品识别系统

我的博客 2121

java 多线程两种方式_Java多线程(二)——常用的实现多线程的两种方式

一、继承Thread类创建线程类Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。每个线程的作用是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java使用线程执行体来代表这段程序流。Thread类的声明如下:public class Thread implements Runnable {}可以看到,Thread本身就实现了Runnable接...

weixin_42499379的博客 318

Linux Component概述和高通component的使用

为了让subsystem按照一定顺序初始化设备才提出来的。subsystem中由很多设备模块,内核加载这些模块的时间不确定。子系统内有些模块是需要依赖其它模块先初始化才能进行自己初始化工作(例如v4l2 subdev和v4l2 video device),这时就要用到component框架。例如v4l2 subdev和v4l2 video device中,谁依赖谁先创建?

lz_1990的专栏 1610

用GraphPad Prism直出单细胞亚群堆叠柱状图

用GraphPad Prism直出单细胞亚群堆叠柱状图

fivehuge的博客 4197

多线程二

一、线程间数据的一致性 volatile关键字:这个关键字表示这个变量有可能发生改变,每次需要的时候需要到内存中的获取(因为系统可能优化将常用的数据保存到寄存器中)。 1.排他锁定。 二、使用C Run-time Library           早期的C Run-time Library有数个的全局变量和静态变量,对于多线程的程序来说,使用这个库可能造成冲突,因此后来又设计了一个多线程

无语的阿辉 890

相机图像质量研究(22)常见问题总结:CMOS期间对成像的影响--光学串扰

光学串扰是一个比较难以理解的光学现象,实际影响往往不大。一、光学串扰产生的原因通常是入射角度太大,光线在不同通道之间产生了混叠二、光学串扰产生的现象光学串扰容易导致迷宫纹。总结本节讲了光学串扰产生的原因,现象。

xiaoshixiu的专栏 1573

二、多线程同步问题

一、线程安全问题 比如同一个账户,加入父亲和儿子同时在不同的窗口同时取钱,比如剩余1000块,父亲取了800,儿子也取了800,不同窗口没有及时同步数据,可能就会实际支出了1600,而这是不允许发生的; - 这种不安全的问题并不是一定会发生,取决于线程的具体调度; - 但是一旦发生,就是灾难性的,必须在代码层面解决; 账户类 public class Account { private double balance; private String name; // set及get及有

weixin_43374578的博客 3484

Unity零基础到入门☀️| 万字教程 讲解Unity中的数据存储 PlayerPrefs、XML、JSON【建议收藏】

本文章是Unity零基础到入门专栏的系列文章。 适合对Unity3D引擎感兴趣的小伙伴学习,偏向于新手学习! 本篇文章就来介绍一下Unity中三种基本的数据存储方式:PlayerPrefs、XML、JSON

努力前行,总会成为自己心中的那道光 8万+

如何在飞腾平台上安装Ubuntu操作系统

注意: 若主板上配置的是NVME硬盘,在进行内核配置时,需要将内核的NEME驱动勾选上,否则移植内核时,无法找到文件系统,进不去操作系统。可以通过rufus软件将镜像做到U盘中,本次使用版本为Rufus 3.9.124 ,其他版本也可以。不要下载live版本的,没有准备网络环境,是一个头疼的事情,笔者暂时没有实现网络安装。将U盘接到主板usb口上,接上串口,显示器,,必需串口有打印才可以安装。可以通过dd命令,将iso安装到U盘。安装的是最小系统,缺少很多命令,需要联网更新,或则更换飞腾专用内核。

技术联盟 2645

Python笔记二之多线程

这一篇笔记介绍一下在 Python 中使用多线程。以下的操作都是在 Python 3.8 版本中试验,不同版本可能有不同之处,需要注意。

weixin_43354181的博客 1266

影楼精修-高低频磨皮算法解析

本文介绍了像素蛋糕软件中的高低频磨皮算法原理及实现思路,抛砖引玉。

Trent1985的专栏 2259

多线程二.

首先,什么是线程安全问题呢?线程安全问题指的是,多个线程同时操作同一个共享资源的时候,可能会出现业务安全问题。下面通过一个取钱的案例给同学们演示一下。案例需求如下场景:小明和小红是一对夫妻,他们有一个共享账户,余额是10万元,小红和小明同时来取钱,并且2人各自都在取钱10万元,可能出现什么问题呢?如下图所示,小明和小红假设都是一个线程,本类每个线程都应该执行完三步操作,才算是完成的取钱的操作。但是真实执行过程可能是下面这样子的。

2302_76719419的博客 901

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

多线程篇二

使用jconsole观察,t1线程为TIMED_WAITING状态(排队等工作 sleep引起),t2线程为BLOCKED状态(由于t1未执行完 产生锁竞争)我们知道一个线程在完成它的工作后才能进行自己的下一步工作,但在期间想穿插别的工作进来就需要控制线程结束的顺序来实现.1.如果线程正在工作中,此时调用thread线程就会阻塞,一直阻塞到thread线程执行结束位置.WAITING 线程在无限等待唤醒。2.如果thread线程已经执行结束了,此时调用join线程,就会直接返回,不会涉及阻塞.

weixin_72981769的博客 1743

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java多线程<二>多线程经典场景

task.get()是阻塞的,最好不要放在主线程中,更不要放在线程创建的路径上,最好在开一个线程,进行归并。多线程对效率的提升体现在多处理器的并行上。这里实现的计算是平均划分数组进行求和,如果不能平均划分就会出错。应该使用归并式的那种划分。明天实现一下多线程的归并排序和多线程的斐波那契数列。

fuzekun的博客 1414

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

二、售票多线程

二、售票多线程 笔记: 1.高内聚低耦合的前提下,线程操作资源类 2.判断/干活/通知 3.多线程交互中,必须要防止多线程的虚假唤醒,也即(判断只用while,不能用if) 固定的编程套路+模板是什么? a) 一言不合,先创建一个资源类(domain、entities、pojo) b) 一个线程start之后不是马上就启动,调度跟底层的cpu有关系 c) 多线程有六种状态Thread.State看api即可,分别是: NEW、RUNNABLE、BLOCKED、WAITING(死等)、TIME

weixin_43868840的博客 180

二、多线程

二、多线程 1、程序、进程、线程的基本概念 程序:是为完成特定任务、用某种语言编写的一组指令的集合,即是一段静态的代码,静态对象 进程:是正在运行的一个程序,是一个动态过程:有它自身的产生、存在和消亡的过程——生命周期,进程作为资源分配的单位 线程:进程可进一步细化为线程,是程序内部的一条执行路径,线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc) 2、使用多线程的优点以及不稳定因素 线程的优点: 提高应用程序的响应 提高计算机系统CPU的利用率 改善程序结构,将即长又杂的进程分

weixin_46203713的博客 156

二、多线程基础

一、基本概念:程序、进程、线程 1、程序(program) 程序是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。 2、进程(process) 进程是程序的一次执行过程,或是正在运行的一个程序。 进程是一个动态的过程:有它自身的产生、存在和消亡的过程。—— 即所谓的生命周期 1. 如:运行中的QQ,运行中的MP3播放器。 2. 程序是静态的,进程是动态的。 3...

XuanAlex的博客 422

C++多线程编码二

lock是一个函数模板,可以支持多个锁对象同时锁定同一个,如果其中一个锁对象没有锁住,lock函数会把已经锁定的对象解锁并进入阻塞,直到多个锁锁定一个对象。try_lock也是一个函数模板,尝试对多个锁对象进行同时尝试锁定,如果锁对象全部锁定,返回-1,如果某一个锁对象尝试锁定是失败,把已经锁定成功的锁对象解锁,并返回这个对象的下标(第一个参数对象,下标从0开始)

2302_80378107的博客 1130

Java多线程(二)线程同步

只有当最后一个非守护线程结束是,守护线程随着JVM一同结束工作,Daemon作用是为其他线程提供便利服务,守护线程最典型的应用就是GC(垃圾回收器),他就是一个很称职的守护者。当一个线程运行到需要同步的语句后,CPU不去执行其他线程中的、可能影响当前线程中的下一句代码的执行结果的代码块,必须等到下一句执行完后才能去执行其他线程中的相关代码块,这就是线程同步。1.在java语言中,引入了同步锁的概念,每个对象都有一个与之关联的内部锁(排他锁),用以保证共享数据的安全性问题。但是,当两个线程同时调用这两。

My_story_begins的博客 1507

二、多线程的实现

多线程实现的三种方式: 1、继承Thread类 是一个支持多线程的功能类,只要一个子类继承就可以实现多线程。在对Thread类进行深入理解之前,我们必须要知道:所有程序的起点是 main() 方法,所有线程也应该有自己的起点,这个起点就是 run() 方法。在多线程的每个主体类中都必须覆写Thread类中所提供的run()方法。 细心点可以发现,Thread类中的 public void run...

weixin_42230348的博客 208

【多线程高并发编程】二 实现多线程的几种方式

本文我们来看看多线程的应用场景,为什么要用多线程,以及实现一个多线程有几种方式。

程序猿学社的博客 1万+

多线程核心语法②

获取线程引用Thread.currentThread(),线程休眠 sleep(),线程状态 getState(),线程安全问题,线程不安全的原因,随机调度,抢占式执行,加锁,锁具有“互斥”,“排他”性。如果synchronized加到static方法上 <=>给类对象加锁

m0_74203999的博客 831

二、多线程安全

多线程安全1.多线程安全问题2.synchronized使用及原理2.1 synchronized 使用2.2 synchronized 原理3.多线程死4.多线程运行状态(生命周期)5.用户线程与守护线程(User与Daemon)6.Join方法7.线程的优先级8.yield()方法 1.多线程安全问题 当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题,但是做读操作是不会发生数据冲突问题。 经典实例:两个窗口同时出售100张票 public class

zcdlove的博客 723

多线程总结二

       上一篇博客主要介绍了多线程的一些基础的知识,接下来就是在java中实现多线程。        在java中实现多线程一共有3种方式:                                            一 . 继承Thread,重写run方法,使得子类覆盖父类的方法,从而达到实现多线程的目的。                                     ...

远方的博客 323
上一篇: 多线程
下一篇: 网络编程
gorgeoustudy
博客等级 码龄9年 5粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值