线程安全

Java中的String,StringBuilder,StringBuffer三者的区别

时光怂恿深爱的人放手 提交于 2020-01-22 02:49:41
  这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。 首先说运行速度,或者说是执行速度, 在这方面运行速度快慢为:StringBuilder > StringBuffer > String   String最慢的原因:   String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。 以下面一段代码为例: String str="abc"; System.out.println(str); str=str+"de"; System.out.println(str);   如果运行这段代码会发现先输出“abc”,然后又输出“abcde”,好像是str这个对象被更改了,其实,这只是一种假象罢了,JVM对于这几行代码是这样处理的,首先创建一个String对象str,并把“abc”赋值给str,然后在第三行中,其实JVM又创建了一个新的对象也名为str,然后再把原来的str的值和“de”加起来再赋值给新的str,而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了,所以,str实际上并没有被更改,也就是前面说的String对象一旦创建之后就不可更改了。所以,

Spring Bean单例与线程安全

那年仲夏 提交于 2020-01-21 20:28:03
一、Spring单例模式及线程安全   Spring框架中的Bean,或者说组件,获取实例的时候都是默认单例模式,这是在多线程开发的时候需要尤其注意的地方。   单例模式的意思是只有一个实例,例如在Spring容器中某一个类只有一个实例,而且自行实例化后并项整个系统提供这个实例,这个类称为单例类。   当多个用户同时请求一个服务时,容器会给每一个请求分配一个线程,这时多个线程会并发执行该请求对应的业务逻辑(成员方法),此时就要注意了,如果该处理逻辑中有对单例状态的修改(体现为该单例的成员属性),则必须考虑线程同步问题。 同步机制的比较:   ThreadLocal和线程同步机制相比有什么优势呢?他们都是为了解决多线程中相同变量的访问冲突问题。   在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。   而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时

Java多线程中static变量的使用

二次信任 提交于 2020-01-21 20:22:31
转自:http://blog.csdn.net/yy304935305/article/details/52456771 有时候,对于在多线程中使用static变量有没有冲突,是否存在安全问题不能十分的确定。在使用过程中有点含糊,总想找点时间好好追究一下,可总因开发项目时间的紧迫而搁浅。我想,没有做进一步的研究而拿项目繁忙说事,这是自己的借口吧! 鲁迅先生曾说过:“时间就像海绵里的水,只要愿挤,总还是有的”。不管肿(怎)么说,这事还是要做的啊。如果越往后推,可能造成的潜在影响更大。这始终是个隐患,不能不除。 不是痛定思痛,而是认识到事情的重要性,就要开始行动了... ... 以上是个人的闲言碎语,不足而看。下面,我们就少言几句进入到技术领域吧! 线程,是我们项目中绕不过的重点领域。提到线程,就常会听到线程安全的术语。那什么是线程安全呢?通俗点说,就是线程访问时不产生资源冲突。其实,这是一个有点难以定义的概念,不是很容易让人一听就懂的概念。“一个类可以被多个线程安全调用就是线程安全的”《 Java 编程并发实践》。 来说说静态变量、实例变量、局部变量在多线程下的安全问题吧! (一)静态变量:线程非安全 1、静态变量:使用static关键字定义的变量。static可以修饰变量和方法,也有static静态代码块。被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说

C# 原子操作 Interlocked

喜夏-厌秋 提交于 2020-01-20 21:53:16
前言 焦虑与恐惧,往往是是因为想要的太多,但行动却太少。将目标放低,制定足以达到目标的计划,并付之于一步一个脚印的行动。当你确信你在前进的时候,自然就不会焦虑;当你的行动为你积累了足够多的正向改变的时候,自然就不会恐惧;当量变中迸发出那么一星星的质变时,你将变的自信。 足够强大,你才会自信。 自信来源于强大的内心,强大的自己 。 开始 Interlocked 提供了方法来实现原子操作,对于多线程共享的变量来说,原子操作保证了线程安全,保证了变量值的正确性。 让我们看一个简单的例子,在下面例子中,我们 new 了 10 个 线程,并启动他们;他们各自循环10次调用 UseSharedValue 方法;在 UseSharedValue 方法中, 我们执行了 threadSharedValue++ 的操作。由于 threadSharedValue 的初始值为0,所以当程序跑完后,我们对于 threadSharedValue 的期望值为100。 using System; using System.Threading; namespace InterlockedExchange_Example { class MyInterlockedExchangeExampleClass { private static int threadSharedValue = 0; //每个线程内,循环10次

转 Java 208道面试题及部分答案 补充部分答案

元气小坏坏 提交于 2020-01-20 08:41:26
转自 https://www.cnblogs.com/chen1005/p/10481102.html ---恢复内容开始--- 一、Java 基础 1.JDK 和 JRE 有什么区别? 答:JRE是java运行时环境,包含了java虚拟机,java基础类库。是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的。   JDK是java开发工具包,是程序员使用java语言编写java程序所需的开发工具包,是提供给程序员使用的 2.== 和 equals 的区别是什么? 答:==是比较两个对象的地址,equals是比较连个对象的内容 3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗? 答:不对!hashCode()相同,不代表连个对象就相同。hashCode值是从hash表中得来的,hash是一个函数,该函数的实现是一种算法,通过hash算法算出hash值,hash表就是 hash值组成的,一共有8个位置。   相反,equals()相同,hashCode()一定相同。这个是正确的! 4.final 在 java 中有什么作用? 答: final的作用随着所修饰的类型而不同: final修饰类中的属性或者变量:无论属性是基本类型还是引用类型, final所起的作用都是变量里面存放的“值”不能变

循环使用CAS实现自旋操作

不想你离开。 提交于 2020-01-20 02:54:20
大家碰到了实现一个线程安全的计数器的需求改怎么做呢?根据经验你应该知道我们要在多线程中实现共享变量的原子性和可见性问题,于是锁成为一个不可避免的话题,下文讨论的是与之对应的无锁CAS。 为什么要无锁 我们一想到在多线程下保证安全的方式,肯定是锁,不管从硬件、操作系统层面都或多或少在使用锁。锁有优缺点吗? 使用锁就需要获得锁、释放锁,CPU需要通过上下文切换和调度管理来进行这个操作,对于一个独占锁,一个线程在持有锁后没有执行结束,其他线程就必须等待,等到前面的线程执行完毕,CPU就会把锁拿出来给其他线程来抢了。锁的这种概念基于一种悲观机制,它总是认为数据会被修改,所以,你在操作一部分代码块之前先加一把锁,操作完成后再释放,这样就安全了。 什么是 CAS 比较并交换(compare and swap,CAS),是原子操作的一种,可用于在多线程编程中实现不被打断的数据交换操作,从而避免多线程同时改写某一数据时由于执行顺序不确定性以及中断的不可预知性产生的数据不一致性问题。该操作通过将内存中的值与指定的数据进行比较,当数值一样时,将内存中的数据替换成新值。 JAVA如何实现 package com.concurrent.program; import java.util.ArrayList; import java.util.Arrays; import java.util.List;

集合

狂风中的少年 提交于 2020-01-19 21:20:06
集合 一、集合框架图(图片来源于网络) 这是两个集合框架接口的总体图分为两个集合接口,分别是Collection接口和map接口 二、collection集合接口 下面的接口主要有:List、Set、Queue; (1)Queue接口与List、Set同一级别,都是继承了Collection接口。 (2)LinkedList既可以实现List接口也可以实现Queue接口。只不过LinkedList实现Queue接口时,Queue接口窄化了对LinkedList的访问权限(参数类型是Queue时只能访问Queue中的方法,不能访问LinkedList的非Queue的方法)。 (3)SortedSet是个接口,它里面(只有TreeSet这一实现可用)的元素一定是有序的。 1、List (1)ArrayList 优点:底层数据结构是数组,查询快;效率高 缺点:增删慢;线程不安全 为什么是线程不安全的? ArrayList的底层源码显示其主要做了两个步骤 ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; a.判断elementData数组容量是否满足需求 b.在elementData对应位置上设置值 具体情况参考博客https://blog.csdn.net

ConcurrentHashMap源码详解(与HashMap/HashTable的比较)

前提是你 提交于 2020-01-19 09:33:00
先看看速度比HashTable快又比HashMap线程安全的------当红明星ConcurrentHashMap具体使用方法: 非常的平淡无奇,跟HashMap和HashTable好像是一样东西。 但是,ConcurrentHashMap其实是融合了HashMap/HashTable这两种Hash表数据结构的优点。我们看源码可以知道: HashTable全部操作方法都是用Java 中自带的synchronized锁强制做同步达到线程安全的,不管是get还是put还是其他一些方法。 而HashMap就没考虑那么多,它的方法中全部没做线程安全锁处理。具体详细的HashMap介绍请看另外一篇博文: https://blog.csdn.net/whiteBearClimb/article/details/103946465 因此我们可以得出结论就是HashMap速度快但是线程不安全;HashTable速度慢但是线程安全。 ConcurrentHashMap就是融合它们二者各自的优点。既是线程安全的,速度又相对能较快。那么是怎么实现的呢?看源码: 继续进去ConcurrentMap看看什么个东西 这些毫无疑问没啥好讲的,我们再看看它最常用的几个方法有什么不同点。 Get方法: Put方法: 这里如果有仔细看过HashMap代码的人瞬间就恍然大悟了,没看过的打开:::https://blog

单例设计模式

余生颓废 提交于 2020-01-18 02:28:38
什么是单例设计模式?  单例模式,是一种常见的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式的方法创建的类在当前进程中只有一个实例。  在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。 单例模式有以下特点: 单例类只能有一个实例 单例类必须自己创建自己的唯一实例 单例类必须给所有的其他对象提供这一实例 具体实现 需要: 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象 在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型 定义一个静态方法返回这个唯一对象 实现一:立即加载/“饿汉模式” /** * 饿汉式:在类初始化的时候,已经创建自己的实例 */ public class Singleton { //1,私有化构造方法 private Singleton(){} //2,创建自己的单例对象 private final static Singleton

学习第十六天

筅森魡賤 提交于 2020-01-16 05:14:56
一: 1.存储键值对的数据 key value->在哈希表结构中 2.key获取hashcode()值一个int的整数,根据hash算法进行计算,算出桶的位置 hash算法: hashcode()值 % 数组的长度 hashcode()值 & 数组的长度-1 ---->数组的长度必须为2的整数幂 3.先判断对应桶中是否已经存在数据,有,判断桶中的数据是否与我当前的key相等,使用equals(),如果相等value覆盖,如果不相等,把数据放入链表的最后 对应桶中是否已经存在数据,没有,那就直接放入桶中 如果equals相等,hashcode一定要保证相等,保证相等的数据桶的位置一样,才会比较equals进行去重 hashcode相等,equals不一定相等,所以我才要放入桶的时候比较equals() 总结: 如果使用hashMap存储数据,key是自定义的引用的数据类型,一定要重写hashcode()和equals()方法 java8:哈希表(数组+链表+红黑树):当桶中的数据超过8个,把结构当前链表结构变为红黑树 初始容量:16 加载因子:0.75 当16*0.75达到临界点12进行扩容 扩容: 扩容位桶的大小 二: Arrays 操作数组的工具类 此类包含用来操作数组(比如排序和搜索)的各种方法 Collections 操作容器的工具类 HashMap 线程不安全,效率较高