synchronized

Java多线程(二)

最后都变了- 提交于 2020-02-12 11:33:30
个人博客 http://www.milovetingting.cn Java多线程(二) 前言 本文为学习Java相关知识所作笔记,参考以下资料: https://github.com/Snailclimb/JavaGuide ,感谢原作者的分享! JAVA 锁 乐观锁 乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,采取在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重复读-比较-写的操作。 java 中的乐观锁基本都是通过 CAS 操作实现的,CAS 是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。 悲观锁 悲观锁是就是悲观思想,即认为写多,遇到并发写的可能性高,每次去拿数据的时候都认为别人会修改,所以每次在读写数据的时候都会上锁,这样别人想读写这个数据就会 block 直到拿到锁。java中的悲观锁就是Synchronized,AQS框架下的锁则是先尝试cas乐观锁去获取锁,获取不到,才会转换为悲观锁,如 RetreenLock。 自旋锁 自旋锁原理非常简单,如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态

Java 多线程 - Synchronized关键字

∥☆過路亽.° 提交于 2020-02-12 05:42:51
目录 1-Synchronized 关键字概述 2- Synchronized关键字作用域 3- Synchronized 原理(反编译指令解释) 正文 1-Synchronized 关键字概述 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。 需要明确的几个问题: synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果 再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。 无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。 每个对象只有一个锁(lock)与之相关联。 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。 2- Synchronized关键字作用域 Java中每一个对象都可以作为锁,这是synchronized实现同步的基础: 普通同步方法,锁是当前实例对象 静态同步方法,锁是当前类的class对象 同步方法块

synchronized

女生的网名这么多〃 提交于 2020-02-12 04:55:39
首先讲一下原子性以及互斥。 举个例子,在32位CPU上执行long(64位)变量的写操作时,会存在多线程下读写不一致的问题。 因为32位CPU下对其写会拆分成两次操作,一次写高32位和一次写底32位,而这个操作无法保证其 原子性 所以产生并发问题了。 原子性 指即一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行,简单的说就是一个或者多个操作在 CPU 执行的过程中不被中断的特性。 互斥 如果 同一时刻只有一个线程执行 则被称之为 互斥 ,把一段需要互斥执行的代码称为 临界区 。如果我们能够保证对共享变量的修改是互斥的,那么,无论是单核 CPU 还是多核 CPU,就都能保证原子性了。 互斥锁 锁是一种通用的技术方案,Java 语言提供的 synchronized 关键字,就是一种互斥锁。synchronized 关键字可以用来修饰方法,也可以用来修饰代码块,通过其修饰的临界区是互斥的,使用方法如下: public class demo{ private final Object monitor = new Object(); // 修饰非静态方法 synchronized void method1() { // 临界区 } // 修饰静态方法 synchronized static void method2() { // 临界区 } // 修饰代码块

Java Synchronized的原理

℡╲_俬逩灬. 提交于 2020-02-12 04:30:02
我们先通过反编译下面的代码来看看Synchronized是如何实现对代码块进行同步的: public class SynchronizedDemo{ public void method(){ synchronized(this){ System.out.println("Method 1 start"); } } } 反编译 可以看到有monitorenter和monitorexit两条指令 关于这两条指令的描述我们参考JVM规范: monitorenter: Each object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows: • If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then

synchronized使用及原理解析

北战南征 提交于 2020-02-12 01:16:12
修饰静态方法、实例方法、代码块 Synchronized修饰静态方法,对类对象进行加锁,是类锁。 Synchronized修饰实例方法,对方法所属对象进行加锁,是对象锁。 Synchronized修饰代码块时,对一段代码块进行加锁,是对象锁。 /** * synchronized示例 * 1、修饰静态方法 * 2、修饰实例方法 * 3、修饰代码块 */ public class SyncDemo2 { private static int num = 0; /** * 修饰静态方法 */ public static synchronized void count1() { for (int i = 0; i < 100000000; i++) { num++; } } /** * 修饰实例方法 */ public synchronized void count2() { for (int i = 0; i < 100000000; i++) { num++; } } /** * 修饰代码块 * 效果与修饰静态方法相同 */ public void count3() { synchronized(SyncDemo2.class) { for (int i = 0; i < 100000000; i++) { num++; } } } /** * 修饰代码块 * 效果与修饰实例方法相同

day13-多线程

时间秒杀一切 提交于 2020-02-11 22:40:40
多线程 线程与进程的区别 进程:进程指的是内存中一个运行的应用,一个进程有多个或一个进程,通常是xxx.exe程序,进程与进程之间资源不共线 线程:一个进程包含一个或多个线程,表示线程之间可以同时进行,线程与线程之间资源可以共享 多线程的好处:多线程可以并发执行,如果没有多线程,只能一个运行结束之后再进行下一个任务,不符合生活实际要求 多线程的调度情况:cpu进行调用,cpu会给线程分配时间片(CPU给线程的运行时间,一般几毫秒到几时毫秒不等),之间是抢占式的,谁抢到时间片,谁执行 并发与并行 并发:某时间段内同时执行 并行:同一个时间同时执行 主线程main 一个简单的Java程序就已经拥有两个线程,一个是主线程(main),一个是堆的垃圾回收(gc)。 Thread实现线程创建与启动 public class Demo { public static void main ( String args [ ] ) { new ThreadDemo ( ) . start ( ) ; //java 1.8写法 new Thread ( ( ) - > { public void run ( ) { //线程主体 } } ) . start ( ) ; } } class ThreadDemo extends Thread { public void run ( ) { //..

123 java锁synchronized相关内容

妖精的绣舞 提交于 2020-02-11 19:05:15
自旋锁:循环等待,不断尝试获取,成功后退出。 乐观锁: 修改数据时发现数据变化则重读数据并修改---假定不冲突 悲观锁:从读数据开始就加锁 -- 假定冲突 独占锁:一把用写,其他线程不能加锁。 共享锁:读,可以加读锁,但不能加写锁。 (不)可重入锁:已经获取锁的线程未释放前重新获取锁,是否阻塞。reentrantlock,synchronized 均可重入 公平锁,非公平锁:是否按顺序拿锁。 synchronized: 对非静态方法加锁this,静态方法加锁:class 可重入,独占锁,悲观锁 单线程内无意义的锁操作,触发jit后会出现锁消除 合并多个无意义的小锁为一个锁--锁粗化。jvm处理时触发jit优化。 实例锁的标记存储在对象头(class meta address、array length、markword)中 ;mark word(hashcode,threadid、lock record address、monitor address,forword address) 状态(unlocked、biased、light-weight lock,heavy-weight lock,marked for gc) 状态和存的值一一对应。 抢锁时:读取对象的mark word存入当前线程;cas操作mark word,新值 local record address(例:轻量级锁

Java 6中的synchronized

馋奶兔 提交于 2020-02-11 18:00:19
0. 前言 在多线程并发编程中Synchronized一直是元老级角色, 很多人都会称呼它为重量级锁, 但是随着Java SE1.6对Synchronized进行了 各种优化 之后,有些情况下它并不那么重了,本文详细介绍了Java SE1.6中 为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁, 以及锁的存储结构和升级过程。 1. 术语定义 术语 英文 说明 CAS Compare and Swap 比较并设置。用于在硬件层面上提供原子性操作。在 Intel 处理器中,比较并交换通过指令cmpxchg实现。 比较是否和给定的数值一致,如果一致则修改,不一致则不修改。 2. 同步的基础 Java中的每一个对象都可以作为锁。 对于同步方法,锁是当前实例对象。 对于静态同步方法,锁是当前对象的Class对象。 对于同步方法块,锁是Synchonized括号里配置的对象。 当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。那么锁存在哪里呢?锁里面会存储什么信息呢? 3. 同步的原理 JVM规范规定JVM基于进入和退出Monitor对象来实现方法同步和代码块同步, 但两者的实现细节不一样。代码块同步是使用monitorenter和monitorexit指令实现,而方法同步是使用另外一种方式实现的,细节在JVM规范里并没有详细说明

synchronized介绍

我是研究僧i 提交于 2020-02-11 17:59:18
1、在多线程并发编程中synchronized一直被称为重量级锁,但是随着Java se1.6 对synchronized进行了各种优化后,有些情况下它就并不那么重了。 synchronized实现同步的基础:每个对象都可以作为锁,具体分为三种情况: 对于普通同步方法,锁的是自己实力对象 对于静态同步方法,锁的是当前类的Class对象 对于同步方法快,锁的是synchronized括号里配置的对象 JVM基于进入和退出Monitor对象来实现方法同步和代码块同步,但是两者实现细节不同: 代码块同步是使用monitorenter和monitorexit指令实现的。 同步方式使用的另一种方法实现。 monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束处和异常处,JVM要保证每个monitorenter和monitorexit成对出现。 任何一个对象都有一个monitor与之关联, 当且一个monitor被持有后,它将处于锁定状态。 线程执行到monitorenter指令时,将尝试获得对象所对应的monitor的所有权,即尝试获得对象的锁。 2、synchronized用的锁是存在Java对象头里的。如果对象是数组类型的话,则JVM用3个字节存储对象头,如果对象是非数组类型的话,则用2个字节存储对象头。 3、锁升级与对比 Java

Java开发中的23种设计模式详解

廉价感情. 提交于 2020-02-11 17:19:17
一、设计模式的分类 总体来说设计模式分为三大类: 1. 创建型模式 共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 2. 结构型模式 共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 3. 行为型模式 共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 4. 其它 并发型模式和线程池模式。用一个图片来整体描述一下: 回到顶部 二、设计模式的原则(先不看) 1、开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。 2、里氏代换原则(Liskov Substitution Principle) 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为