线程安全

Collections.synchronizedList 、CopyOnWriteArrayList、Vector介绍、源码浅析与性能对比【文末福利】

痞子三分冷 提交于 2020-02-01 09:25:05
ArrayList线程安全问题 众所周知, ArrayList 不是线程安全的,在并发场景使用 ArrayList 可能会导致add内容为null,迭代时并发修改list内容抛 ConcurrentModificationException 异常等问题。java类库里面提供了以下三个轮子可以实现线程安全的List,它们是 Vector Collections.synchronizedList CopyOnWriteArrayList 本文简要的分析了下它们线程安全的实现机制并对它们的读,写,迭代性能进行了对比。 Vector 从JDK1.0开始, Vector 便存在JDK中, Vector 是一个线程安全的列表,底层采用数组实现。其线程安全的实现方式非常粗暴: Vector 大部分方法和 ArrayList 都是相同的,只是加上了 synchronized 关键字,这种方式严重影响效率,因此,不再推荐使用 Vector 了。JAVA官方文档中这样描述: If a thread-safe implementation is not needed, it is recommended to use ArrayList in place of Vector. 如果不需要线程安全性,推荐使用ArrayList替代Vector 关键源码如下: public synchronized

J2SE(10)之多线程(线程安全)

[亡魂溺海] 提交于 2020-02-01 05:07:34
1、线程安全 在多线程系统中,当多个线程共享同一份资源时,会出现线程不安全的情况。我们可以使用关键字synchronized加锁来解决线程不安全的问题。 1.1 同步方法 在方法上加上synchronized关键字,普通同步方法默认的锁对象是当前对象this,对于静态同步方法,锁是当前类的Class对象。 public synchronized void test2(){ //方法体 } 1.2 同步方法块 用关键字synchronized修饰可能存在线程不安全的代码块,锁对象是我们指定的引用类型的对象,基本类型不能作为锁。 synchronized(锁对象){ //可能存在线程不安全的代码 } 1.3 以售票讲解线程同步 public class SynDemo01 { /** * @param args */ public static void main(String[] args) { //真实角色 Web12306 web= new Web12306(); //代理 Thread t1 =new Thread(web,"路人甲"); Thread t2 =new Thread(web,"黄牛已"); Thread t3 =new Thread(web,"攻城师"); //启动线程 t1.start(); t2.start(); t3.start(); } } /** *

Linux线程互斥(线程安全)

僤鯓⒐⒋嵵緔 提交于 2020-01-31 03:15:18
线程安全 线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。 简单点来说: 因为多线程为一个进程下的多个执行流, 那么久意味着这些线程都共用同一份虚拟地址空间, 这样以来个个线程之间就会有很多数据是共享的 , 比如全局数据, 堆上的内存, 而如果多个线程同时操作一个这样的资源, 那么就会出现不可预知的结果, 比如如下的抢票程序 可以看一下的实例: # include <iostream> # include <pthread.h> # include <stdio.h> # include <stdlib.h> # include <unistd.h> using namespace std ; int ticket = 100 ; //thread_mutex_t mutexs; void * TekeTi ( void * agr ) { while ( 1 ) { // pthread_mutex_lock(&mutexs); if ( ticket > 0 ) { printf ( "我抢到%d,我是线程%ld\n" , ticket , ( long ) agr ) ; ticket -- ; usleep ( 10 ) ; //

java提供了String、StringBuffer和StringBuilder三个类来封装字符串(String three brothers)(网络摘抄)

。_饼干妹妹 提交于 2020-01-31 03:14:13
字符串类 字符串就是一连串的字符序列,java提供了String、StringBuffer和StringBuilder三个类来封装字符串,并提供了一系列方法来操作字符串对象。 String、StringBuffer和StringBuilder之间的区别如下: String创建的字符串是不可变的,当使用String创建一个字符串后,该字符串在内存中是一个不可改变的字符序列,如果改变字符串变量的值,其实际是在内存中创建一个新的字符串,字符串变量将引用新创建的字符串地址,而原来的字符串在内存中已然存在且内容不变,直至Java的垃圾回收系统对其进行销毁。 StringBuffer创建的字符串是可变的当使用StringBuffer创建一个字符串后,该字符串的内容可以通过append()、insert()、setCharAt()等方法进行改变,而字符串变量所引用的地址一直不变。如果想获得StringBuffer的最终内容,可以通过调用它的toString()方法转换成一个String对象。 StringBuilder是JDK1.5新增的一个类,与StringBuffer类似也是创建一个可变的字符串,不同的是StringBuffer是线程安全的,而StringBuilder没有实现线程安全,因此性能较好。通常,如果只需要创建一个内容可变的字符串对象,不涉及线程安全、同步方面的问题

多线程、线程安全、线程状态、等待唤醒机制、线程池

醉酒当歌 提交于 2020-01-30 23:42:53
主要内容 线程 同步 线程状态 等待与唤醒案例 线程池 教学目标 说出进程的概念 说出线程的概念 能够理解并发与并行的区别 能够开启新线程 能够描述Java中多线程运行原理 能够使用继承类的方式创建多线程 能够使用实现接口的方式创建多线程 能够说出实现接口方式的好处 能够解释安全问题的出现的原因 能够使用同步代码块解决线程安全问题 能够使用同步方法解决线程安全问题 能够说出线程6个状态的名称 能够理解线程通信概念 能够理解等待唤醒机制 能够描述Java中线程池运行原理 能够理解函数式编程相对于面向对象的优点 第一章 多线程 我们在之前,学习的程序在没有跳转语句的前提下,都是由上至下依次执行,那现在想要设计一个程序,边打游戏边听歌,怎么设计? 要解决上述问题,咱们得使用多进程或者多线程来解决. 1.1 并发与并行 并发 :指两个或多个事件在 同一个时间段内 发生。 并行 :指两个或多个事件在 同一时刻 发生(同时发生)。 在操作系统中,安装了多个程序,并发指的是在一段时间内宏观上有多个程序同时运行,这在单 CPU 系统中,每一时刻只能有一道程序执行,即微观上这些程序是分时的交替运行,只不过是给人的感觉是同时运行,那是因为分时交替运行的时间是非常短的。 而在多个 CPU 系统中,则这些可以并发执行的程序便可以分配到多个处理器上(CPU),实现多任务并行执行

Java并发编程实践笔记

对着背影说爱祢 提交于 2020-01-30 11:09:15
1, 保证线程安全的三种方法 : a, 不要跨线程访问共享变量 b, 使共享变量是 final类型的 c, 将共享变量的操作加上同步 2, 一开始就将类设计成线程安全的 , 比在后期重新修复它 ,更容易 . 3, 编写多线程程序 , 首先保证它是正确的 , 其次再考虑性能 . 4, 无状态或只读对象永远是线程安全的 . 5, 不要将一个共享变量裸露在多线程环境下 (无同步或不可变性保护 ) 6, 多线程环境下的延迟加载需要同步的保护 , 因为延迟加载会造成对象重复实例化 7, 对于 volatile 声明的数值类型变量进行运算 , 往往是不安全的 (volatile 只能保证可见性 , 不能保证原子性 ). 详见 volatile 原理与技巧中 , 脏数据问题讨论 . 8, 当一个线程请求获得它自己占有的锁时 ( 同一把锁的嵌套使用 ), 我们称该锁为可重入锁 . 在 jdk1.5 并发包中 , 提供了可重入锁的 java 实现 -ReentrantLock. 9, 每个共享变量 , 都应该由一个唯一确定的锁保护 . 创建与变量相同数目的 ReentrantLock, 使他们负责每个变量的线程安全 . 10,虽然缩小同步块的范围 , 可以提升系统性能 . 但在保证原子性的情况下 , 不可将原子操作分解成多个 synchronized块 . 11, 在没有同步的情况下 ,

Java设计模式-单例模式的7种写法详解(上)

余生颓废 提交于 2020-01-30 10:11:31
Java设计模式-单例模式的7种写法详解(上) 参照B站尚硅谷官方视频资源:https://www.bilibili.com/video/av57936239?p=33 文章目录 Java设计模式-单例模式的7种写法详解(上) 0.前言 1.饿汉式(静态常量)实现单例模式 1.1 实现步骤 1.2 具体编码 1.3 测试验证 1.4 阶段小结 2.饿汉式(静态代码块)实现单例模式 2.1 实现步骤 2.2 具体编码 2.3 测试验证 2.4 阶段小结 3.懒汉式(线程不安全)实现单例模式 3.1实现步骤 3.2具体编码 3.3测试验证 3.4阶段小结 4.懒汉式(线程安全,同步方法)实现单例模式 4.1实现步骤 4.2具体编码 4.3测试验证 4.4阶段小结 5.一种错误的写法:懒汉式(同步代码块) 5.1实现步骤 5.2具体编码 5.3测试验证 5.4阶段小结 0.前言 单例模式: 确保此类只有一个实例,并提供获取实例的方法。 作用: 可以保持在一个应用程序生命周期内,所引用对象的实例均为同一个 使用场景:例如工具类,使用了单例模式后,可避免重复创建实例造成的资源浪费。 单例模式分为以下7种: 饿汉式(静态常量) 饿汉式(静态代码块) 懒汉式(线程不安全) 懒汉式(线程安全,同步方法) 双重检查 静态内部类 枚举 也可说是5种,只是懒汉饿汉各自又有2种不同的实现方式。

单例模式

谁说我不能喝 提交于 2020-01-29 16:23:32
设计模式大家都很熟悉,今天来记录下最基础也最简单的单例模式 单例模式分为两类,一是饿汉式,另外就是相对的懒汉式 想来看看饿汉式 常见的实现方式如下: 1 public class SingletonHungry { 2 private static SingletonHungry instance = new SingletonHungry(); 3 4 private String token; 5 6 private SingletonHungry() { 7 token = System.currentTimeMillis() + ""; 8 } 9 10 public static SingletonHungry getInstance() { 11 return instance; 12 } 13 14 public String getToken() { 15 return token; 16 } 17 } 新增token来验证线程安全 来个线程安全的 public class SingletonHungrySafe { private static String token; //jvm加载时会实例化 private static class Holder { private static SingletonHungrySafe INSTANCE = new

集合家族——List集合汇总

别等时光非礼了梦想. 提交于 2020-01-29 09:59:25
一、概述   List继承了Collection,是 有序 的列表。   可重复数据   实现类有ArrayList、LinkedList、Vector、Stack等 ArrayList 是基于数组实现的,是一个数组队列。可以动态的增加容量! LinkedList 是基于链表实现的,是一个双向循环列表。可以被当做堆栈使用! Vector 是基于数组实现的,是一个矢量队列,是线程安全的! Stack 是基于数组实现的,是栈,它继承与Vector,特性是FILO(先进后出) 二、情景使用   1. 当集合中对插入元素数据的速度要求不高,但是要求快速访问元素数据,则使用ArrayList!   2. 当集合中对访问元素数据速度不做要求不高,但是对插入和删除元素数据速度要求高的情况,则使用LinkedList!   3.当集合中有多线程对集合元素进行操作时候,则使用Vector!但是现在BVector现在一般不再使用,如需在多线程下使用,可以用CopyOnWriteArrayList,在java.util.concurrent包下。   4.当集合中有需求是希望后保存的数据先读取出来,则使用Stack! 三、各自简介    3.1 ArrayList     ArrayList 是最常用的 List 实现类,内部是通过 数组 实现的,它允许对元素进行 快速随机访问

aslist,gloang线程安全可排序的list

↘锁芯ラ 提交于 2020-01-29 05:23:13
aslist aslist(A Sorted List)是golang语言实现的线程安全可排序的list。便捷的调用方式,使开发者快速入门使用。 前言 近来有喷子喷我,说golang有排序框架何苦要自己造轮子。我只想说中国的拿来主义思想就是导致今天中国为何终始没有自主研发的操作系统,没有自己的芯片。你跟我说这句话就像问"已经有了Java为什么还要学Golang、为什么男人有了老婆还想有小三"。因为需求嘛。各种各样的需求,有人在乎性能,有人在乎便捷,有人在乎二者都在乎。你要是觉得我造的轮子不好,你自己就去造一个更好的。不要在这里说一些显得你很浅薄的话。aslist就是给在乎便捷、不想了解底层算法的人使用。不喜欢你可以走。 为什么要设计aslist? 如果你是从java转golang开发,你就会发现golang中对数组(array)、切片(slice)的封装比较原生。这对开发者来说过去java日常对List方便操作放在golang中是非常痛苦的。如排序(sort)、栈(stack)操作、先进先出(FIFO)、左进右出(LIRI)......本人深耕java多年深刻体会到你的痛苦,所以借鉴java对list体验设计的思路封装了这个轻量级的aslist。使你在golang中能找回java的感觉。 为什么Range、ClearTargets、Pop不能像Java一样使用泛型? 没有办法