synchronized

并发基础知识 — 线程安全性

删除回忆录丶 提交于 2019-12-23 18:55:54
前段时间看完了《并发编程的艺术》,总感觉自己对于并发缺少一些整体的认识。今天借助《Java并发编程实践》,从一些基本概念开始,重新整理一下自己学过并发编程。从并发基础开始,深入进去,系统学习一下并发编程。   编写线程安全的代码,核心在于要对状态访问操作进行管理,特别是对共享的(Shared)和可变的(Mutable)状态的访问。对象的状态是指存储在状态变量(实例或静态域)中的数据。对象的状态还可能包括其他依赖对象的域。(Map.Entry)   一个对象是否需要时线程安全的,取决于该对象是否被多线程访问。这指的是程序中访问对象的方式,而不是对象要实现的功能。要使得对象是线程安全的,要采用同步机制来协同对对象可变状态的访问。Java常用的同步机制是 Synchronized ,还包括 volatile 类型的变量,显示锁以及原子变量。   线程安全的程序是否完全由线程安全的类构成?答案是否定的,完全由线程安全的类构成的程序并不一定是线程安全的,线程安全类中也可以包含非线程安全的类。只有当类中仅包含自己的状态时,线程安全类才有意义! 什么是线程安全性?   当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么这个类就是线程安全的。   正确性:某个类的行为与其规范相一致。

同步中的四种锁synchronized、ReentrantLock、ReadWriteLock、StampedLock

巧了我就是萌 提交于 2019-12-23 17:48:33
1.前言 锁就像一把钥匙,需要加锁的代码就像一个房间。出现互斥操作的典型场景:多人同时想进同一个房间争抢这个房间的钥匙(只有一把),一人抢到钥匙,其他人都等待这个人出来归还钥匙,此时大家再次争抢钥匙循环下去。 作为终极实战系列,本篇用java语言分析锁的原理(源码剖析)和应用(详细代码),根据锁的作用范围分为:JVM锁和分布式锁。如理解有误之处,还请指出。 2.单JVM锁(进程级别) 程序部署在一台服务器上,当容器启动时(例如tomcat),一台JVM就运行起来了。本节分析的锁均只能在单JVM下生效。因为最终锁定的是某个对象,这个对象生存在JVM中,自然锁只能锁单JVM。这一点很重要。如果你的服务只部署一个实例,那么恭喜你,用以下几种锁就可以了。 1.synchronized同步锁 2.ReentrantLock重入锁 3.ReadWriteLock读写锁 4.StampedLock戳锁 由于之前已经详细分析过原理+使用,各位直接坐飞机吧: 同步中的四种锁synchronized、ReentrantLock、ReadWriteLock、StampedLock 3.分布式锁(多服务节点,多进程) 3.1基于数据库锁实现 场景举例: 卖商品,先查询库存>0,更新库存-1。 1.悲观锁: select for update(一致性锁定读) 查询官方文档如上图,事务内起作用的行锁

高并发课程笔记

放肆的年华 提交于 2019-12-23 12:10:05
高并发课程笔记 (一) 第一课 synchronized 线程重入 (一)第二课 是否可以在同步方法运行期间,插入一个非同步方法? 脏读问题 一个同步方法可以调用另一个同步方法吗? (一)第三课 一个同步方法可以调用另一个同步方法吗? synchronized 方法异常 volatile 关键字 volatile 的问题 (一)第四课 原子类 synchronized 优化 避免将锁定对象的引用变成另外的对象 不要用字符串常量作为锁定对象 (一)第五六课 (二) 第一二三课 ReenTrantLock ReenTrantLock与synchronized的区别 trylock() lockInterruptibly 公平锁 生产者消费者模式 (二)第四课 线程局部变量 (三)Java的并发容器类 (三)第一二课 线程的单例模式 创建线程安全的单例模式, 高并发容器开头 火车站卖票第一版 火车站卖票第二版(Vector容器) 火车站卖票第三版(LinkedList +synchronized) 火车站卖票第四版(并发容器 ConcurrentLinkedQueue) (三)第三四课 并发容器 Concurrent 类的Map 写时复制容器 ConcurrentLinkedQueue LinkedBlockingQueue ArrayBlockingQueue DelayQueue

搞懂这几个锁用法,多线程就懂一半了

…衆ロ難τιáo~ 提交于 2019-12-23 05:23:15
0x01: synchronized 在Java中synchronized关键字被常用于维护数据一致性。 synchronized机制是给共享资源上锁,只有拿到锁的线程才可以访问共享资源,这样就可以强制使得对共享资源的访问都是顺序的。 Java开发人员都认识synchronized,使用它来实现多线程的同步操作是非常简单的,只要在需要同步的对方的方法、类或代码块中加入该关键字,它能够保证在同一个时刻最多只有一个线程执行同一个对象的同步代码,可保证修饰的代码在执行过程中不会被其他线程干扰。使用synchronized修饰的代码具有原子性和可见性,在需要进程同步的程序中使用的频率非常高,可以满足一般的进程同步要求。 synchronized (obj) { //方法 ……. } synchronized实现的机理依赖于软件层面上的JVM,因此其性能会随着Java版本的不断升级而提高。 到了Java1.6,synchronized进行了很多的优化,有适应自旋、锁消除、锁粗化、轻量级锁及偏向锁等,效率有了本质上的提高。在之后推出的Java1.7与1.8中,均对该关键字的实现机理做了优化。 需要说明的是,当线程通过synchronized等待锁时是不能被Thread.interrupt()中断的,因此程序设计时必须检查确保合理,否则可能会造成线程死锁的尴尬境地。 最后

Kotlin 知识

大憨熊 提交于 2019-12-23 03:58:43
1 lateinit vs by lazy 一 lateinit 只修饰var, by lazy只修饰val 1.lazy{} 只能用在val类型 ( lazy 应用于单例模式(if-null-then-init-else-return),而且当且仅当变量被第一次调用的时候,委托方法才会执行。 ), lateinit 只能用在var类型 2.lateinit不能用在可空的属性上和java的基本类型上 3.lateinit可以在任何位置初始化并且可以初始化多次。而lazy在第一次被调用时就被初始化,想要被改变只能重新定义 4.lateinit 有支持(反向)域(Backing Fields) https://www.jianshu.com/p/99e0672e8268 2 特点:扩展(属性和方法) 3 @JVM注解相关 https://www.jianshu.com/p/2ca358b6db3d class MainActivity : AppCompatActivity() { @Volatile var aa = 3 companion object { @Synchronized //在 comppanion 中生成public final synchronized void test() fun test(): Unit { } @Synchronized

java之Stack详细介绍

我怕爱的太早我们不能终老 提交于 2019-12-23 03:21:15
概要 学完 Vector 了之后,接下来我们开始学习Stack。Stack很简单,它继承于Vector。学习方式还是和之前一样,先对Stack有个整体认识,然后再学习它的源码;最后再通过实例来学会使用它。 内容包括: 第1部分 Stack介绍 第2部分 Stack源码解析(基于JDK1.6.0_45) 第3部分 Vector示例 转载请注明出处: http://www.cnblogs.com/skywang12345/p/3308852.html 第1部分 Stack介绍 Stack简介 Stack是栈。它的特性是: 先进后出 (FILO, First In Last Out)。 java工具包中的Stack是继承于 Vector (矢量队列)的,由于Vector是通过数组实现的,这就意味着, Stack也是通过数组实现的 , 而非链表 。当然,我们也可以将LinkedList当作栈来使用!在“ Java 集合系列06之 Vector详细介绍(源码解析)和使用示例 ”中,已经详细介绍过Vector的数据结构,这里就不再对Stack的数据结构进行说明了。 Stack的继承关系 java.lang.Object ↳ java.util.AbstractCollection<E> ↳ java.util.AbstractList<E> ↳ java.util.Vector<E> ↳

java 内存模型

隐身守侯 提交于 2019-12-23 02:41:03
java 内存模型 文章目录 java 内存模型 计算机内存模型 并发编程特性 Java Memory Model JMM 的实现 原子性 可见性 有序性 计算机内存模型 当程序在运行过程中,会将运算需要的数据从主存复制一份到 CPU 的高速缓存当中,那么 CPU 进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中 当 CPU 要读取一个数据时,首先从一级缓存中查找,如果没有找到再从二级缓存中查找,如果还是没有就从三级缓存或内存中查找 在 CPU 和主存之间增加缓存,在多线程场景下就可能存在 缓存一致性问题 ,也就是说,在多核 CPU 中,每个核的自己的缓存中,关于同一个数据的缓存内容可能不一致 为了使处理器内部的运算单元能够尽量的被充分利用,处理器可能会对输入代码进行乱序执行处理。这就是 处理器优化 除了现在很多流行的处理器会对代码进行优化乱序处理,很多编程语言的编译器也会有类似的优化,比如 Java 虚拟机的即时编译器(JIT)也会做 指令重排 并发编程特性 原子性 是指在一个操作中就是 cpu 不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行 可见性 是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值 有序性 即程序执行的顺序按照代码的先后顺序执行

生产者消费者问题虚假唤醒

て烟熏妆下的殇ゞ 提交于 2019-12-23 00:30:32
生产者消费者问题演示及解决 问题一: package com . mock ; import org . junit . jupiter . api . Test ; public class TestProducerAndConsumer { @Test public void test ( ) { Product p = new Product ( ) ; new Thread ( new Producer ( p ) , "生产者1" ) . start ( ) ; new Thread ( new Consumer ( p ) , "消费者1" ) . start ( ) ; } } class Producer implements Runnable { private Product product ; public Producer ( Product product ) { this . product = product ; } @Override public void run ( ) { for ( int i = 0 ; i < 10 ; i ++ ) { product . produce ( ) ; } } } class Consumer implements Runnable { private Product product ; public

多线程学习笔记(2)

情到浓时终转凉″ 提交于 2019-12-22 22:30:57
四、线程同步 4.1.ReentranLock 有两种机制防止代码块受到并发访问的干扰,java语言提供了一个synchronized关键字达到这一目的,以及在jdk5.0引入了ReentrantLoc类 先看看ReentranLOck,这个是jdk1.5添加 myLock.Lock(); try{ 执行语句 } finally { myLock.unLock } 这一结构确保任何时刻只有一个线程进入try执行任务,一旦一个线程用锁封锁了对象,其他任何线程都无法访问lock语句,当其他线程调用的时候,将会进入阻塞状态,直到前一个线程释放锁对象,即unLock(); 另外,把解锁操作放在finally语句中很重要,可以确保不管try区的代码是否抛出异常,锁都可以被释放,如果没用被释放,那其他正在阻塞的线程将被永远阻塞。 举一个例子 public class Bank{ Lock bankLock = new ReentrantLOck(); public void transfer(int from ,int to,int amount) { bankLock.lock(); try { System.out.println(Thread.currentThread()); amount[from] -= amount; amount[from] += amount; }

类锁与对象锁的不冲突性

和自甴很熟 提交于 2019-12-22 18:56:28
synochronized 关键字,内置锁或者监视器锁,也是互斥锁,一次只允许一个线程进入被锁住的代码块。 作用:保证线程的原子性和可见性。 synchronized修饰静态方法获取的是类锁(类的字节码文件对象),synchronized修饰普通方法或代码块获取的是 对象锁 。 它俩是不冲突的,也就是说:获取了类锁的线程和获取了对象锁的线程是不冲突的! 下边为具体代码 package ace; /* * synchronized修饰静态方法获取的是类锁(类的字节码文件对象),synchronized修饰普通方法或代码块获取的是对象锁。 它俩是不冲突的,也就是说:获取了类锁的线程和获取了对象锁的线程是不冲突的! */ import java.util.Arrays; import java.util.Vector; import java.util.concurrent.locks.ReentrantLock; public class SynchoronizedDemo { //synchronized修饰非静态方法 public synchronized void function() throws InterruptedException { for (int i = 0; i <3; i++) { Thread.sleep(1000); System.out.println(