synchronized

数据结构(集合)学习之List

北城余情 提交于 2020-02-16 18:39:36
集合 框架关系图: Collection接口下面有三个子接口:List、Set、Queue。此篇是关于List<E>的简单学习总结。 List(有序、可重复): List里存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有一系列和索引相关的方法,查询速度快。因为往list集合里插入或删除数据时,会伴随着后面数据的移动,所有插入删除数据速度慢。 List常用的子类:ArrayList。(面试常问的:Vector、ArrayList、LinkedList之间的区别)。 ArrayList: public class ArrayList<E> extends AbstractList<E> implements List<E> (继承AbstractList类,实现List接口) 方法摘要(标黄为常用方法) Modifier and Type 方法 描述 void add ​(int index, E element) 在此列表中的指定位置插入指定的元素。 boolean add ​( E e) 将指定的元素追加到此列表的末尾。 boolean addAll ​(int index, Collection <? extends E > c) 将指定集合中的所有元素插入到此列表中,从指定的位置开始。 boolean addAll ​( Collection <?

Java牛客 -- 专项练习(5)

|▌冷眼眸甩不掉的悲伤 提交于 2020-02-16 09:33:47
前因: 记录在牛客上刷题的错题记事本 1.在java7中,下列哪个说法是正确的: A : ConcurrentHashMap使用synchronized关键字保证线程安全 B : HashMap实现了Collection接口 C : Arrays.asList方法返回java.util.ArrayList对象 D : SimpleDateFormat对象是线程不安全的 答案选D, A、ConcurrentHashMap在JDK1.7的时候,使用Segment这个数据结构,利用锁分段技术保证了线程安全,JDK1.8的时候,Segment这个数据结构就废了,开始使用Synchronized+CAS保证线程安全。 B、HashMap,没有实现Collection,其实Map和Collection是集合框架中独立的两大接口。 C、Arrays.asList返回的也是ArrayList,不过这是个Arrays中的内部类,实现了List接口,继承了AbstractList,但是内部类中并没有重写涉及结构性变化的方法,所以一旦调用结构性变换的函数,例如add,会出现运行时异常UnsupportedOperationException。 D、DateFormat这个接口的实现类都是不安全的。 2. true、false、null、sizeof、goto、synchronized

java集合之vector容器

眉间皱痕 提交于 2020-02-15 16:06:21
学完 ArrayList 和 LinkedList 之后,我们接着学习Vector。 第1部分 Vector介绍 第2部分 Vector数据结构 第3部分 Vector源码解析(基于JDK1.6.0_45) 第4部分 Vector遍历方式 第5部分 Vector示例 转载请注明出处: http://www.cnblogs.com/skywang12345/p/3308833.html 第1部分 Vector介绍 Vector简介 Vector 是 矢量队列 ,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。 Vector 继承了AbstractList,实现了List;所以, 它是一个队列,支持相关的添加、删除、修改、遍历等功能 。 Vector 实现了RandmoAccess接口,即 提供了随机访问功能 。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。 Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。 和ArrayList不同, Vector中的操作是线程安全的 。 Vector的构造函数 Vector共有4个构造函数 // 默认构造函数

Java集合框架源码(四)——Vector

孤人 提交于 2020-02-15 16:05:52
第1部分 Vector介绍 Vector简介 Vector 是 矢量队列 ,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。 Vector 继承了AbstractList,实现了List;所以, 它是一个队列,支持相关的添加、删除、修改、遍历等功能 。 Vector 实现了RandmoAccess接口,即 提供了随机访问功能 。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。 Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。 和ArrayList不同, Vector中的操作是线程安全的 。 Vector的构造函数 Vector共有4个构造函数 // 默认构造函数 Vector() // capacity是Vector的默认容量大小。当由于增加数据导致容量增加时,每次容量会增加一倍。 Vector(int capacity) // capacity是Vector的默认容量大小,capacityIncrement是每次Vector容量增加时的增量值。 Vector(int capacity, int capacityIncrement) //

深入分析synchronized的实现原理

烈酒焚心 提交于 2020-02-15 00:38:06
基础概念   synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时可以保证共享变量对内存可见性。   Java中每一个对象都可以作为锁,这是synchronized实现同步的基础: 普通同步方法,锁是当前实例对象 静态同步方法,锁是当前类的class对象 同步方法块,锁是括号里面的对象   当一个线程访问同步代码块时,它首先是需要得到锁才能执行同步代码,当退出或者抛出异常时必须要释放锁。 底层实现 如何来实现这个机制呢?我们先看如下一段简单代码: public class SynchronizedTest{ public synchronized void test1(){ } public void test2(){ synchronized(this){ } } public static void main(String []args){ } } 利用javap工具查看生成的class 文件信息来分析synchronize的实现   从上图可以看出,同步代码块是使用monitorenter和monitorexit指令实现的,同步方法(在这看不出来需要看JVM底层实现)依靠的是方法修饰符上的ACC_SYNCHRONIZED实现。    在java语言中存在两种内建的synchronized语法:1、synchronized语句;2

转载---乐观锁和悲观锁

冷暖自知 提交于 2020-02-14 21:45:35
本文转载自链接: https://blog.csdn.net/qq_34337272/article/details/81072874 何谓悲观锁与乐观锁 乐观锁对应于生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好于另外一种人。 悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。 乐观锁 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。 两种锁的使用场景

Java多线程基础2

久未见 提交于 2020-02-14 14:51:32
1.线程加锁   多个线程需要共享对同一个数据的访问。如果每个线程都会调用一个修改共享数据状态的方法,那么,这些线程将会互相影响对方的运行。在Java语言中,引入对象互斥锁的概念,保证共享数据操作的完整性。每个对象都对应一个可称为“互斥锁”的标记,这个标记保证在任一时刻,只能有一个线程访问对象。就像上一篇博客讲到用多线程模拟售票时,会出现两个车站卖同一张票的时候,这种情况就需要我们在对卖票时加锁,有一个线程访问这段代码时,别的线程就不能访问,保证不会发生两个线程同时访问同一个数据的情况。java的加锁方式有以下两种:   ①synchronized同步代码块   当某个对象用修饰时,表明该对象在任一时刻只能由一个线程访问。   语法: synchronized(this){ //需要同步的代码; }   示例: public void run() { while(sign) { synchronized (this) { if(ticket >= 1) { System.out.println(Thread.currentThread().getName() + ":" + this.ticket--); }else{          sign = false;       } } } }   或者 public synchronized void sale(){ ticket-

JavaSE学习笔记(12)---线程

北战南征 提交于 2020-02-13 23:43:46
JavaSE学习笔记(12)---线程 多线程 并发与并行 并发 :指两个或多个事件在 同一个时间段内 发生。 并行 :指两个或多个事件在 同一时刻 发生(同时发生)。 在操作系统中,安装了多个程序,并发指的是在一段时间内宏观上有多个程序同时运行,这在单 CPU 系统中,每一时刻只能有一道程序执行,即微观上这些程序是分时的交替运行,只不过是给人的感觉是同时运行,那是因为分时交替运行的时间是非常短的。 而在多个 CPU 系统中,则这些可以并发执行的程序便可以分配到多个处理器上(CPU),实现多任务并行执行,即利用每个处理器来处理一个可以并发执行的程序,这样多个程序便可以同时执行。目前电脑市场上说的多核 CPU,便是多核处理器,核 越多,并行处理的程序越多,能大大的提高电脑运行的效率。 注意:单核处理器的计算机肯定是不能并行的处理多个任务的,只能是多个任务在单个CPU上并发运行。同理,线程也是一样的,从宏观角度上理解线程是并行运行的,但是从微观角度上分析却是串行运行的,即一个线程一个线程的去运行,当系统只有一个CPU时,线程会以某种顺序执行多个线程,我们把这种情况称之为线程调度。 线程与进程 进程 :是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建

彻底理解synchronized

喜欢而已 提交于 2020-02-13 12:41:22
1. synchronized简介 在学习知识前,我们先来看一个现象: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class SynchronizedDemo implements Runnable { private static int count = 0; public static void main(String[] args) { for (int i = 0; i < 10; i++) { Thread thread = new Thread(new SynchronizedDemo()); thread.start(); } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("result: " + count); } @Override public void run() { for (int i = 0; i < 1000000; i++) count++; } } 开启了10个线程,每个线程都累加了1000000次,如果结果正确的话自然而然总数就应该是10 * 1000000 = 10000000

新问题整理(高并发)

微笑、不失礼 提交于 2020-02-12 20:57:04
一、HashMap 是不是线程安全? HashMap在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新的扩容数组中, 在多线程的环境下,存在同时其他的元素也在进行put操作,如果hash值相同,可能出现同时在同一数组下用链表表示,造成闭环,导致在get时会出现死循环,所以HashMap是线程不安全的 (多线程会导致 HashMap 的 node 链表形成环状的数据结构产生死循环) 1.1、如何变得安全: Hashtable:通过 synchronized 来保证线程安全的,独占锁,悲观策略。吞吐量较低,性能较为低下 ConcurrentHashMap:JUC 中的线程安全容器,高效并发。ConcurrentHashMap 的 key、value 都不允许为 null 1.2、jdk1.8相对于jdk1.7的优化 由 数组+链表 的结构改为 数组+链表+红黑树。 拉链过长会严重影响hashmap的性能,所以1.8的hashmap引入了红黑树,当链表的长度大于8时,转换为红黑树的结构 优化了高位运算的hash算法:h^(h>>>16) 将hashcode无符号右移16位,让高16位和低16位进行异或。 二、ConcurrentHashMap 的实现方式 1.7