synchronized

精确解释java的volatile之可见性、原子性、有序性(通过汇编语言)

我是研究僧i 提交于 2019-12-02 18:52:00
一、实验环境: 1、Idea代码编辑器 2、jdk1.8.0_92 3、win10_x64 二、易产生误解的Java字段Volatile volatile保证了可见性,但是并不保证原子性!!! 1.volatile关键字的两层语义   一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:   1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。   2)禁止进行指令重排序。 volatile的可见性,即任何时刻只要有任何线程修改了volatile变量的值,其他线程总能获取到该最新值。具体更多实现可以参阅缓存一致性协议。 2.那么volatile为什么又不能保证原子性呢? 以volatile int i = 10;i++;为例分析: i++实际为load、Increment、store三个操作。 某一时刻线程1将i的值load取出来,放置到cpu缓存中,然后再将此值放置到寄存器A中,然后A中的值自增1(寄存器A中保存的是中间值,没有直接修改i,因此其他线程并不会获取到这个自增1的值)。如果在此时线程2也执行同样的操作,获取值i==10,自增1变为11,然后马上刷入主内存。此时由于线程2修改了i的值,实时的线程1中的i==10的值缓存失效,重新从主内存中读取,变为11

被synchronized修饰的方法调用了没有被synchronized修饰的方法,是否是线程安全

杀马特。学长 韩版系。学妹 提交于 2019-12-02 18:51:00
1 被synchronized修饰的方法调用了没有被synchronized修饰的方法,是否线程安全? /** * (1)被synchronized修饰的方法调用了没有被synchronized修饰的方法,是否线程安全? * (2)线程安全问题都是由全局变量及静态变量引起的,若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的; * 若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能导致数据不一致 * (3)线程安全是指多个线程在执行同一段代码的时候采用加锁机制,线程不安全就是不提供加锁机制保护 * (4)在下面的例子中,如果method2方法都是通过method1调用的,那么程序执行没有问题,是线程安全的,但是method2也有可能同时被其他的线程调用,可能会对全局变或者静态变量进行修改,所以说method2线程不安全 */ public class SynchronizedDemo1 { public static void main(String[] args) { new Thread(() -> { method1(); }).start(); new Thread(() -> { method2(); }).start(); } private static synchronized void method1() {

多线程与高并发

泄露秘密 提交于 2019-12-02 18:08:57
1.Callable和Runnable I Callable定义的方法是call,而Runnable定义的方法是run。 II Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。 III Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。 Runnable 不做具体介绍 通过实现Callable接口来创建Thread线程:其中,Callable接口(也只有一个方法)定义如下: public interface Callable<V> { V call() throws Exception; } 步骤1:创建实现Callable接口的类SomeCallable<Integer>(略); 步骤2:创建一个类对象: Callable<Integer> oneCallable = new SomeCallable<Integer>(); 步骤3:由Callable<Integer>创建一个FutureTask<Integer>对象: FutureTask<Integer> oneTask = new FutureTask<Integer>(oneCallable); 注释:FutureTask<Integer>是一个包装器,它通过接受Callable<Integer>来创建

Java多线程常见面试题

牧云@^-^@ 提交于 2019-12-02 18:03:23
1. 并行和并发有什么区别? 并行(Parallel):指两个或者多个事件在同一时刻发生,即同时做不同事的能力。例如垃圾回收时,多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。 并发(Concurrent):指两个或多个事件在同一时间间隔内发生,即交替做不同事的能力,多线程是并发的一种形式。例如垃圾回收时,用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续运行,而垃圾收集程序运行于另一个CPU上。 2. 线程和进程的基本概念、线程的基本状态以及状态之间的关系? 一个线程是进程的一个顺序执行流程。一个进程中的全部线程共享同一个堆空间。线程本身有一个供程序执行时的栈,一个进程中可以包含多个线程。 线程的 基本状态 :新建、就绪、运行状态、阻塞状态、死亡状态 新建状态:利用NEW运算创建了线程对象,此时线程状态为新建状态,调用了新建状态线程的start()方法,将线程提交给操作系统,准备执行,线程将进入到就绪状态。 就绪状态:由操作系统调度的一个线程,没有被系统分配到处理器上执行,一旦处理器有空闲,操作系统会将它放入处理器中执行,此时线程从就绪状态切换到运行时状态。 运行状态:线程正在运行的过程中,碰到调用Sleep()方法,或者等待IO完成,或等待其他同步方法完成时,线程将会从运行状态,进入到阻塞状态。 死亡状态:线程一旦脱离阻塞状态时

如何避免死锁?我们有套路可循

爱⌒轻易说出口 提交于 2019-12-02 18:03:06
写在前面 上一篇文章 共享资源那么多,如何用一把锁保护多个资源? 文章我们谈到了银行转账经典案例,其中有两个问题: 单纯的用 synchronized 方法起不到保护作用(不能保护 target) 用 Account.class 锁方案,锁的粒度又过大,导致涉及到账户的所有操作(取款,转账,修改密码等)都会变成串行操作 如何解决这两个问题呢?咱们先换好衣服穿越回到过去寻找一下钱庄,一起透过现象看本质,dengdeng deng....... 来到钱庄,告诉柜员你要给铁蛋儿转 100 铜钱,这时柜员转身在墙上寻找你和铁蛋儿的账本,此时柜员可能面临三种情况: 理想状态: 你和铁蛋儿的账本都是空闲状态,一起拿回来,在你的账本上减 100 铜钱,在铁蛋儿账本上加 100 铜钱,柜员转身将账本挂回到墙上,完成你的业务 尴尬状态: 你的账本在,铁蛋儿的账本被其他柜员拿出去给别人转账,你要等待其他柜员把铁蛋儿的账本归还 抓狂状态: 你的账本不在,铁蛋儿的账本也不在,你只能等待两个账本都归还 放慢柜员的取账本操作,他一定是先拿到你的账本,然后再去拿铁蛋儿的账本,两个账本都拿到(理想状态)之后才能完成转账,用程序模型来描述一下这个拿取账本的过程: 我们继续用程序代码描述一下上面这个模型: class Account { private int balance; // 转账 void transfer

线程同步

一世执手 提交于 2019-12-02 16:27:16
synchronized(this){同步块} 第一种处理方式 this 必须是唯一的 在后续的开发中,我们一般用这个唯一的类的字节码信息来表示唯一的。 boolean getmoney(int m) throws InterruptedException { synchronized (Money.class){ if (m<=money){ Thread.sleep(1); money-=m; System.out.println(Thread.currentThread().getName()+"取钱成功,剩余"+money); return true; } } System.out.println(Thread.currentThread().getName()+"余额不足,剩余"+money); return false; } 第二种 synchronized 线程同步方法 synchronized boolean getmoney(int m) throws InterruptedException { if (m<=money){ Thread.sleep(1); money-=m; System.out.println(Thread.currentThread().getName()+"取钱成功,剩余"+money); return true; } System

java锁_IO_NIO_AIO_BIO_GC_Jvm

被刻印的时光 ゝ 提交于 2019-12-02 16:19:59
# 多线程环境下如何保证一个共享数据的一致性? # 使用synchronized关键字 使用Lock锁 使用Atomic原子类 多线程之不使用锁保证数据的一致性:多线程共享变量的情况下,为了保证数据的一致性,往往需要对这些变量的访问进行加锁。 而锁本身又会带来一些问题和开销。Immutable Object模式的意图:通过使用对外可见的状态不可变的对象(即Immutable对象), 使得共享对象“天生”具有线程安全性,而无需额外添加同步访问控制 # 锁synchronize、Lock、ReenTrantLock 的区别 # 1.1 相似点: 这两种同步方式有很多相似之处,它们都是加锁方式同步,而且都是阻塞式的同步,也就是说当如果一个线程获得了对象锁,进入了同步块,其他访问该同步块的线程都必须阻塞在同步块外面等待,而进行线程阻塞和唤醒的代价是比较高的(操作系统需要在用户态与内核态之间来回切换,代价很高,不过可以通过对锁优化进行改善)。 1.2 区别: 1.2.1 API层面 这两种方式最大区别就是对于Synchronized来说,它是java语言的关键字,是原生语法层面的互斥,需要jvm实现。而ReentrantLock它是JDK 1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配合try/finally语句块来完成。 synchronized既可以修饰方法

synchronized block - lock more than one object

人盡茶涼 提交于 2019-12-02 16:12:13
I'm modelling a game where multiple players (threads) move at the same time. The information of where a player is located at the moment is stored twice: the player has a variable "hostField" that references to a field on the board and every field has an ArrayList storing the players that are currently located at this field. I'm not very happy with the fact that I have redundant information, but I found no way avoiding that without looping through a big dataset. However, when a player moves from one field to another, I'd like to make sure (1) the redundant information stays linked (2) nobody

Java synchronized and happens before [duplicate]

ぐ巨炮叔叔 提交于 2019-12-02 16:11:24
问题 This question already has answers here : How to understand happens-before consistent (4 answers) Closed last year . A synchronized statement establishes a happens-before relation. But im not sure about the details. In http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html one can read An unlock (synchronized block or method exit) of a monitor happens-before every subsequent lock (synchronized block or method entry) of that same monitor I want to know if i

我掏空了各大搜索引擎,给你整理了154道Java面试题!

久未见 提交于 2019-12-02 15:50:20
转自: https://mp.weixin.qq.com/s?__biz=MzA4NjgxMjQ5Mg==&mid=2665762822&idx=1&sn=8f5f0cc4a678c184b78088590ceea1ef&chksm=84d20225b3a58b3383e9b3bf07ee8649c6872d133f2ef3b2aaf9d681a7a9df22f0df3d81203b&token=123684230&lang=zh_CN#rd Java集合22题 ArrayList 和 Vector 的区别。 说说 ArrayList,Vector, LinkedList 的存储性能和特性。 快速失败 (fail-fast) 和安全失败 (fail-safe) 的区别是什么? hashmap 的数据结构。 HashMap 的工作原理是什么? Hashmap 什么时候进行扩容呢? List、Map、Set 三个接口,存取元素时,各有什么特点? Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用 == 还是 equals()? 它们有何区别? 两个对象值相同 (x.equals(y) == true),但却可有不同的 hash code,这句话对不对? heap 和 stack 有什么区别。 Java 集合类框架的基本接口有哪些? HashSet 和 TreeSet