线程安全

StringBuffer

房东的猫 提交于 2020-03-28 15:01:10
1.StringBuffer StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringBuffer要更加适合一些。 在StringBuffer类中存在很多和String类一样的方法,这些方法在功能上和String类中的功能是完全一样的。 但是有一个最显著的区别在于,对于 StringBuffer 对象的每次修改都会改变对象自身,这点是和 String 类最大的区别。 另外由于StringBuffer是线程安全的。即全局范围的StringBuffer和StringBuilder,两个线程不能同时修改StringBuffer中的内容,而能同时修改StringBuilder中的东西。比如说一个StringBuffer对象,一个线程调用StringBuffer.append("a"),另一个线程调用StringBuffer.append("b"),那它的数据肯定包含"a",和"b"这两个字符。但同样的操作对StringBuilder来说,最终的结果是,数据可能只有"a",也可能只有"b"或同时有"a“也有”b",这是不确定的 1

String、Stringbuffer、StringBuffer回顾

∥☆過路亽.° 提交于 2020-03-28 14:56:45
前言 :   久了没用到,一下子就忘了。。,参考文章: https://www.cnblogs.com/su-feng/p/6659064.html 、 https://baijiahao.baidu.com/s?id=1629804867201303563&wfr=spider&for=pc 区别:这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。 一、运行速度:   StringBuilder > StringBuffer > String String最慢的原因 :    String为字符串常量,   StringBuilder和StringBuffer均为字符串变量,   String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。 二、 线程安全 :    StringBuilder是线程不安全的,而StringBuffer是线程安全的   不严格要求安全时,常用效率比较高的 StringBuilder 三、总结: 1、在字符串不经常发生变化的业务场景优先使用String(代码更清晰简洁)。如 常量的声明 ,少量的字符串操作(拼接,删除等)。 2、在 单线程 情况下,如有大量的字符串操作情况,应该使用StringBuilder来操作字符串。不能使用String"+"来拼接而是使用StringBuilder

面试刷题16:synchronized和ReentrantLock的区别?

こ雲淡風輕ζ 提交于 2020-03-27 20:23:48
java并发编程是程序员基本技能。 我是李福春,我在准备面试,今天的题目是: synchronized和ReentrantLock的区别? 这两货都是java提供的同步机制,提供了互斥语义和可见性,当一个线程获得资源之后,其它竞争资源的线程必须等待或者堵塞。 区别如下: 线程安全 线程安全说的是多线程场景下,共享可修改状的数据的正确性。 从语义来看,保证线程安全的方法有2: 1, 封装起来,数据不共享,私有化。 2, 数据不可修改,自然不存在线程不安全。final,immutable; 线程安全的3个特性: 隔离性: 相关操作不会被其它线程干扰 顺序性: 线程内的串行语义,避免指令重排; 可见性: 线程的本地变量修改应该反馈到主内存上,使用volatile关键字。 先来看一个线程不安全的例子: package org.example.mianshi.concurrent; /** * 线程不安全例子,共享数据sharedState * @author lifuchun */ public class ThreadSafeSample { public int sharedState; public void nonSafeAction() { while (sharedState < 100000) { int former = sharedState++; int latter

多线程(三):线程安全

喜夏-厌秋 提交于 2020-03-23 02:38:50
一.一个典型的Java线程安全例子 1 public class ThreadTest { 2 3 public static void main(String[] args) { 4 Account account = new Account("123456", 1000); 5 DrawMoneyRunnable drawMoneyRunnable = new DrawMoneyRunnable(account, 700); 6 Thread myThread1 = new Thread(drawMoneyRunnable); 7 Thread myThread2 = new Thread(drawMoneyRunnable); 8 myThread1.start(); 9 myThread2.start(); 10 } 11 12 } 13 14 class DrawMoneyRunnable implements Runnable { 15 16 private Account account; 17 private double drawAmount; 18 19 public DrawMoneyRunnable(Account account, double drawAmount) { 20 super(); 21 this.account = account; 22

40个Java多线程问题总结

旧城冷巷雨未停 提交于 2020-03-22 20:00:51
40个问题汇总 1、多线程有什么用? 一个可能在很多人看来很扯淡的一个问题:我会用多线程就好了,还管它有什么用?在我看来,这个回答更扯淡。所谓"知其然知其所以然","会用"只是"知其然","为什么用"才是"知其所以然",只有达到"知其然知其所以然"的程度才可以说是把一个知识点运用自如。OK,下面说说我对这个问题的看法: (1)发挥多核CPU的优势 随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4核、8核甚至16核的也都不少见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。 单核CPU上所谓的"多线程"那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程"同时"运行罢了 。多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。 (2)防止阻塞 从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了

C# 线程 基本同步

那年仲夏 提交于 2020-03-22 12:49:59
第二部分: 基本同步 同步要点 到目前为止,我们已经描述了如何在线程上启动任务,配置线程以及双向传递数据。我们还描述了局部变量如何专用于线程,以及如何在线程之间共享引用,从而允许它们通过公共字段进行通信。 下一步是同步:协调线程的动作以实现可预测的结果。当线程访问相同的数据时,同步特别重要。在该区域搁浅非常容易。 同步构造可以分为四类: 简单的组织方法 它们等待另一个线程完成或等待一段时间。 Sleep,Join和Task.Wait是简单的阻止方法。 锁定构造 这些限制了可以一次执行某些活动或一次执行一段代码的线程数。排它锁定结构是最常见的-一次仅允许一个线程,并且允许竞争线程访问公共数据而不会互相干扰。标准的排他锁定结构是锁(Monitor.Enter / Monitor.Exit),互斥锁和SpinLock。非排他的锁定构造是Semaphore,SemaphoreSlim和读取器/写入器锁定 信号结构 这些允许线程暂停,直到接收到来自另一个线程的通知为止,从而避免了无效的轮询。常用的信号设备有两种:事件等待句柄和监视器的等待/脉冲方法。 Framework 4.0引入了CountdownEvent和Barrier类。 非阻塞同步构造 这些通过调用处理器原语来保护对公共字段的访问。 CLR和C#提供以下非阻塞构造:Thread.MemoryBarrier,Thread

[读书笔记]《Effective Java》第10章并发

回眸只為那壹抹淺笑 提交于 2020-03-20 07:44:06
第66条:同步访问共享的可变数据 同步的意义。 正确地使用同步可以保证没有任何方法会看到对象处于不一致的状态中。 进入同步方法或者同步代码块的每个线程,都看到由同一个锁保护的之前所有的修改效果。 Java语言规范保证读或者写一个变量是原子的,除非这个变量的类型为long或者double。 对于原子数据的读取,Java语言规范并不保证一个线程写入的值对于另一个线程将是可见的。 对于共享的数据,即使数据是原子可读写的,也要使用同步。 活动性失败:因为JVM的优化,部分代码无法执行。 1 /** 2 * 共享原子可读写的变量不使用同步访问. 3 * Created by itlivemore on 17-7-1. 4 */ 5 public class StopThread { 6 private static boolean stopThread; 7 8 public static void main(String[] args) throws InterruptedException { 9 Thread backGroundThread = new Thread(new Runnable() { 10 @Override 11 public void run() { 12 int i = 0; 13 while (!stopThread) { 14 System.out

死锁以及线程安全案例

跟風遠走 提交于 2020-03-18 17:26:45
并发编程专题内容: 串行和并行: 串行:一个线程在处理操作 并行:多个线程在处理同一个操作 什么叫做并发编程:在多线程环境下,应用程序的执行 并发编程的目的:充分运用到资源,提高程序的效率 什么情况下用到并发编程: 1.在线程阻塞时,导致应用程序停止 2.处理任务时间过长时,可以创建子任务,来进行分段处理 3.间断任务执行 一.并发编程中待解决的问题 1.并发编程中频繁上下文切换的问题频繁上下文切换,可能会带来一定的性能开销 如何减少上下文性能开销: 1.无锁并发编程 2.CAS 3.使用最少线程数量 4.协程:在单线程环境下进行多任务的调度,可以在多任务之间进行任务切换 2.并发编程中死锁问题 多个线程在抢占资源,但是抢占过程当中资源如果被占用,会造成阻塞,如果多个线程互抢资源时,就会造成死锁情况,死锁会导致应用程序的阻塞 案例: public class DeadLockDemo { //资源 private static final Object HAIR_A=new Object(); private static final Object HAIR_B=new Object(); public static void main(String[] args) { //第一个人 new Thread(()->{ //护住自己的头发 synchronized (HAIR_A){

Map集合

社会主义新天地 提交于 2020-03-17 11:04:49
Map集合概述    存储键值对应关系的数据,也就是映射关系。 Map集合特点   Map 集合中不能存在相同的键,一个键只能对应一个值,键相同值覆盖。   Map 集合的数据结构 只跟键有关 ,跟值无关。   基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。 了解Map集合,Map集合有哪些实现 hashMap hashTable LinkedHashMap TreeMap ConcurrentHashMap HashMap和HashTable的区别    HashMap不是线程安全的,HashTable是线程安全的一个Collection。   HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。   HashMap是一个接口 是map接口的子接口,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。   HashMap允许null key和null value,而hashtable不允许。   HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable