热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java并发机制详解及其在数据安全性保障中的应用方案

《JAVA啃骨头》之 Java SE 章节java的并发机制及并发机制下数据安全问题的解决方案 说在前面:线程和进程 在提及多线程的时候,必须引入线程这个概念,而线程往往是和进程联系在一起的。线程和进


《JAVA啃骨头》之 Java SE 章节

java的并发机制及并发机制下数据安全问题的解决方案
  • 说在前面:线程和进程
    在提及多线程的时候,必须引入线程这个概念,而线程往往是和进程联系在一起的。线程和进程的关系,举一个例子,一家公司是一个进程,网景和京东是不同的两家公司,他们就是两个不同的进程,本质上来说,进程实际上指的是一个应用程序。而线程可以将其看做是刘强东和奶茶妹妹,他们是两个线程,在京东这个进程里面有两个线程。
    进程(网景)和进程(京东)之间的资源是不会共享的,而同一个进程下的线程之间是会共享一部分资源的,当然并不是全部的资源都会共享。(刘强东和奶茶妹妹是有一部分的秘密可以共享的,但是他们也有各自的小秘密。)

  • 并发机制及存在价值
    如果把一个火车站看做是一个进程的话,那么多条检票窗口就是不同的线程,检票窗口多,检票效率就高。多线程的存在也同样是为了提高效率。
    一个线程一个栈,多个栈并行,工作效率就高。

  • 对于单核的CPU来说,多线程的本质其实是单线程
    一个CPU就像一个大脑,一个大脑只能同时执行一个任务,对于多核的CPU来说,确实可以做到真正的并行,但对于单核CPU来说,一个时间只能同时进行一个任务,所以,对于单核的CPU来说,多线程其实本质上是单线程。
    那么问题来了,既然单核的CPU的多线程其实本质是单线程,我们为何还称之为多线程呢?再举个栗子,小明准备写作业,可他有两个作业要写,但是他不想一个写完了再写另外一个,所以他想了一个特别的方法,一个作业写一个字,之后再写另一个作业,也只写一个字,这样轮流写,最终,我们可以看做他的两个作业是同时写完的。我们可以把小明看做是一个CPU,同时只能写一个作业(一个线程),但是,由于他在两个作业之间来回切换(抢夺时间片,获得执行权),总的来看,其实就是实现了同时完成两个作业(多线程并发)。

  • 多线程的实现方式
    java已经将多线程实现了,我们只需要继承就行了。

    第一种方式:编写一个类,直接继承java.lang.Thread,重写run方法。

    // 定义线程类
    public class MyThread extends Thread{
    public void run(){

    }
    }
    // 创建线程对象
    MyThread t = new MyThread();
    // 启动线程。
    t.start();

    第二种方式:编写一个类,实现java.lang.Runnable接口,实现run方法。

    // 定义一个可运行的类
    public class MyRunnable implements Runnable {
    public void run(){

    }
    }
    // 创建线程对象
    Thread t = new Thread(new MyRunnable());
    // 启动线程
    t.start();

    注意:第二种方式实现了接口,比较常用,因为一个类实现了接口,它还可以去继承其它的类,更灵活。(java支持单继承,支持多实现)因此,在使用多线程的时候,常常采用第二种方式。

  • 多并发下数据安全问题
    如果两个线程同时对一个数据进行修改,在一个线程获取数据后,还未将修改的数据返回,而另一个线程在此时获取的数据,那么,就会出现数据安全问题。
    多线程并发的数据安全问题的存在有三个条件:存在对数据的修改、多线程、共享数据。

  • 多并发环境下追求数据安全
    首先需要明确,虽然我们追求高效率,但是,数据的安全永远是需要放在第一位的,因此,在两个需要作出选择的时候,我们要首选数据安全,也正因此,我们在具备上述三个条件的时候,就不能采取多线程机制,只能采取单线程机制(线程同步机制)。

  • 多并发环境下数据安全的解决方案
    java的数据存在于三种变量里:


属性位置位置个数是否满足上述三个条件是否存在线程安全问题
实例变量堆中1 个有可能
静态变量方法区1个有可能
局部变量多个不满足

以后,存储数据常常采用数据结构的方式进行存储数据。如果使用局部变量的话:建议使用:StringBuilder。因为局部变量不存在线程安全问题,选择StringBuilder。StringBuffer效率比较低。

ArrayList是非线程安全的。
Vector是线程安全的。
HashMap HashSet是非线程安全的。
Hashtable是线程安全的。

synchronized是一种锁机制,synchronized有三种写法:

第一种:同步代码块:灵活
synchronized(线程共享对象){
同步代码块;
}
第二种:在实例方法上使用synchronized
表示共享对象一定是this
并且同步代码块是整个方法体。

第三种:在静态方法上使用synchronized
表示找类锁。
类锁永远只有1把。
就算创建了100个对象,那类锁也只有一把。

对象锁:1个对象1把锁,100个对象100把锁。
类锁:100个对象,也可能只是1把类锁。

我们以后开发中应该怎么解决线程安全问题?是一上来就选择线程同步synchronize吗?不是,synchronized会让程序的执行效率降低,用户体验不好。系统的用户吞吐量降低。用户体验差。在不得已的情况下再选择线程同步机制。

第一种方案:尽量使用局部变量代替“实例变量和静态变量”。
第二种方案:如果必须是实例变量,那么可以考虑创建多个对象,这样
实例变量的内存就不共享了。(一个线程对应1个对象,100个线程对应100个对象,
对象不共享,就没有数据安全问题了。)
第三种方案:如果不能使用局部变量,对象也不能创建多个,这个时候
就只能选择synchronized了。线程同步机制。

  • 多并发的使用场景
    多并发也叫做高并发,高并发的应用场景有很多,比如:12306的秒杀、淘宝双十一的抢购。对于不同的并发量,可以有不同的解决方案…


推荐阅读
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • 多线程基础概览
    本文探讨了多线程的起源及其在现代编程中的重要性。线程的引入是为了增强进程的稳定性,确保一个进程的崩溃不会影响其他进程。而进程的存在则是为了保障操作系统的稳定运行,防止单一应用程序的错误导致整个系统的崩溃。线程作为进程的逻辑单元,多个线程共享同一CPU,需要合理调度以避免资源竞争。 ... [详细]
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
  • 本文探讨了如何利用Java代码获取当前本地操作系统中正在运行的进程列表及其详细信息。通过引入必要的包和类,开发者可以轻松地实现这一功能,为系统监控和管理提供有力支持。示例代码展示了具体实现方法,适用于需要了解系统进程状态的开发人员。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • MySQL 5.7 学习指南:SQLyog 中的主键、列属性和数据类型
    本文介绍了 MySQL 5.7 中主键(Primary Key)和自增(Auto-Increment)的概念,以及如何在 SQLyog 中设置这些属性。同时,还探讨了数据类型的分类和选择,以及列属性的设置方法。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 在C#编程中,设计流畅的用户界面是一项重要的任务。本文分享了实现Fluent界面设计的技巧与方法,特别是通过编写领域特定语言(DSL)来简化字符串操作。我们探讨了如何在不使用`+`符号的情况下,通过方法链式调用来组合字符串,从而提高代码的可读性和维护性。文章还介绍了如何利用静态方法和扩展方法来实现这一目标,并提供了一些实用的示例代码。 ... [详细]
  • Spring框架中枚举参数的正确使用方法与技巧
    本文详细阐述了在Spring Boot框架中正确使用枚举参数的方法与技巧,旨在帮助开发者更高效地掌握和应用枚举类型的数据传递,适合对Spring Boot感兴趣的读者深入学习。 ... [详细]
  • 在PHP中实现腾讯云接口签名,以完成人脸核身功能的对接与签名配置时,需要注意将文档中的POST请求改为GET请求。具体步骤包括:使用你的`secretKey`生成签名字符串`$srcStr`,格式为`GET faceid.tencentcloudapi.com?`,确保参数正确拼接,避免因请求方法错误导致的签名问题。此外,还需关注API的其他参数要求,确保请求的完整性和安全性。 ... [详细]
  • 在安装并配置了Elasticsearch后,我在尝试通过GET /_nodes请求获取节点信息时遇到了问题,收到了错误消息。为了确保请求的正确性和安全性,我需要进一步排查配置和网络设置,以确保Elasticsearch集群能够正常响应。此外,还需要检查安全设置,如防火墙规则和认证机制,以防止未经授权的访问。 ... [详细]
  • Python全局解释器锁(GIL)机制详解
    在Python中,线程是操作系统级别的原生线程。为了确保多线程环境下的内存安全,Python虚拟机引入了全局解释器锁(Global Interpreter Lock,简称GIL)。GIL是一种互斥锁,用于保护对解释器状态的访问,防止多个线程同时执行字节码。尽管GIL有助于简化内存管理,但它也限制了多核处理器上多线程程序的并行性能。本文将深入探讨GIL的工作原理及其对Python多线程编程的影响。 ... [详细]
  • 本文深入解析了Java 8并发编程中的`AtomicInteger`类,详细探讨了其源码实现和应用场景。`AtomicInteger`通过硬件级别的原子操作,确保了整型变量在多线程环境下的安全性和高效性,避免了传统加锁方式带来的性能开销。文章不仅剖析了`AtomicInteger`的内部机制,还结合实际案例展示了其在并发编程中的优势和使用技巧。 ... [详细]
author-avatar
宁艺汉先生
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有