synchronized

高并发编程

浪子不回头ぞ 提交于 2020-01-13 03:35:43
(一)高并发编程基础知识 这里涉及到一些基础的概念,我重新捧起了一下《实战 Java 高并发程序设计》这一本书,感觉到心潮澎湃,这或许就是笔者叙述功底扎实的魅力吧,喜欢。对于并发的基础可以参照一下我之前写过的一篇博文: Java学习笔记(4)——并发基础 1)多线程和单线程的区别和联系? 答: 在单核 CPU 中,将 CPU 分为很小的时间片,在每一时刻只能有一个线程在执行,是一种微观上轮流占用 CPU 的机制。 多线程会存在线程上下文切换,会导致程序执行速度变慢,即采用一个拥有两个线程的进程执行所需要的时间比一个线程的进程执行两次所需要的时间要多一些。 结论:即采用多线程不会提高程序的执行速度,反而会降低速度,但是对于用户来说,可以减少用户的响应时间。 面试官:那使用多线程有什么优势? 解析:尽管面临很多挑战,多线程有一些优点仍然使得它一直被使用,而这些优点我们应该了解。 答: (1)资源利用率更好 想象一下,一个应用程序需要从本地文件系统中读取和处理文件的情景。比方说,从磁盘读取一个文件需要5秒,处理一个文件需要2秒。处理两个文件则需要: 1| 5秒读取文件A 2| 2秒处理文件A 3| 5秒读取文件B 4| 2秒处理文件B 5| --------------------- 6| 总共需要14秒 从磁盘中读取文件的时候,大部分的CPU时间用于等待磁盘去读取数据。在这段时间里

volatile和synchronized

六眼飞鱼酱① 提交于 2020-01-13 03:35:05
volatile是变量修饰符,而synchronized则是作用于代码,方法和变量。 int i1; int geti1() {return i1;} volatile int i2; int geti2() {return i2;} int i3; synchronized int geti3() {return i3;} 1.geti1()是得到储存在当前线程中i1的数值,而多个线程又多份i1变量的拷贝,这些i1可能不相同。(另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。) 在JAVA内存模型的,有main memory(主内存区域),存放着变量当前的准确值,每个线程也有自己的memory(例如寄存器),为了性能,一个线程会在自己的memory中保存要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory的值,或者main memory的值不一致的情况。因此实际上存在一种可能:main memory的值i1值是1,线程1里的i1是2,线程2里的i1值是3,这在线程1和线程2都改变了他们各自的i1值,而且这个改变还没来得及传给main memory 或其他线程时就会发生。 2.geti2() 得到的是main memory的i2数值。一个变量声明为volatile

volatile和synchronized

别等时光非礼了梦想. 提交于 2020-01-13 03:33:56
这个可能是最好的对比 volatile 和 synchronized 作用的文章了。 volatile 是一个变量修饰符,而 synchronized 是一个方法或块的修饰符。所以我们使用这两种关键字来指定三种简单的存取变量的方式。 int i1; int geti1() {return i1;} volatile int i2; int geti2() {return i2;} int i3; synchronized int geti3() {return i3;} geti1() 在 当前线程 中立即获取在 i1 变量中的值。线程可以获得变量的本地拷贝,而所获得的变量的值并不一定与其他线程所获得的值相同。特别是,如果其他的线程修改了 i1 的值,那么当前线程获得的 i1 的值可能与修改后的值有所差别。实际上, Java 有一种主内存的机制,使用一个主内存来保存变量当前的正确的值。线程将变量的值拷贝到自己独立的内存中,而这些线程的内存拷贝可能与主内存中的值不同。所以实际当中可能发生这样的情况,在主内存中 i1 的值为 1 ,线程 1 和线程 2 都更改了 i1 ,但是却没把更新的值传回给主内存或其他线程中,那么可能在线程 1 中 i1 的值为 2 ,线程 2 中 i1 的值却为 3 。 另一方面, geti2() 可以有效的从主内存中获取 i2 的值。一个 volatile

volatile和synchronized

╄→гoц情女王★ 提交于 2020-01-13 03:32:16
版权声明:本文为博主原创文章,未经博主允许不得转载。 http://www.cnblogs.com/jokermo/ 0. 前言 转载请注明出处: http://www.cnblogs.com/jokermo/ volatile和synchronized都是解决多线程安全问题的方法,为了了解与使用这两个修饰符,首先需要了解什么是多线程安全问题。即多线程安全问题发生的原因。多线程安全问题产生的原因可以概括为两点: 线程任务中处理到 共享数据 。 线程任务中有多条 共享数据操作 ,一条线程在操作共享数据的过程时,另一条线程参与了运算,造成了数据错误。 解决多线程问题的思想: 只要保证多条操作共享的代码在某一时间段内被同一条线程操作,在执行期间不允许其他线程参与运算。这下就运用到了 volatile 和 synchronized 了。 1.Java内存模型简称 JMM (Java Memory Model) JMM用来屏蔽不同硬件和操作系统的内存访问差异,期望Java程序在各种平台上都能实现一致的内存访问效果。 主内存: 主内存可以简单理解为计算机当中的内存,但又不完全等同。主内存被所有的线程所共享,对于一个共享变量(比如静态变量,或是堆内存中的实例)来说,主内存当中存储了它的“本尊”。 工作内存: 工作内存可以简单理解为计算机当中的CPU高速缓存,但又不完全等同

多线程同步方法

被刻印的时光 ゝ 提交于 2020-01-13 02:17:53
当一个方法被关键字synchronized声明后,就只允许一个线程来操作这个方法。也就是指一次只能让一个线程运行。 package com.zwq.impl; public class SynThread { public static void main(String[] args) { //创建SynThreadTest类的实例对象 SynThreadTest synThreadTest = new SynThreadTest(); //创建线程并启动线程 new Thread(synThreadTest).start(); System.out.println(synThreadTest.call()); } } class SynThreadTest implements Runnable{ private int x; private int y; //定义SynThreadTest的同步方法 //重写Runnable接口的run()方法,声明synchronized public synchronized void run() { for(int i=0;i<5;i++){ x++; y++; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System

Java_多线程实现同步

二次信任 提交于 2020-01-13 01:56:47
多线程之间实现同步 理解线程安全 synchronized用法 死锁 Java内存模型 Vlolatile 关键字 ThreadLock 关键字 理解线程安全 什么是线程安全? 当多个线程同时对共享的同一个 全局变量或静态变量 做写的操作时 ,可能会发生数据冲突问题,也就是线程安全问题。 但是 做读操作是不会发生数据冲突问题 。 线程安全解决办法 : 使用多线程之间同步synchronized或使用锁(lock)。 原理: 同一时间内,只让当前一个线程进行对数据进行执行操作。当当前线程执行完成后释放锁,才能让其他线程进行操作执行。避免了同时对数据的操作,这样的话就可以解决线程的不安全问题,也就实现了数据的同步。 synchronized用法: synchronized有两种用法: 第一种:将可能会发生线程安全问题的代码,给包括起来,称为同步代码块。 代码如下: synchronized(锁){   //可能会发生线程冲突问题的代码块 } 第二种: 在方法上修饰synchronized,称为同步函数。 代码如下: public synchronized void 方法名() {   //可能会发生线程冲突问题的代码块 } 若在方法上加上 static 静态关键字则成为静态同步函数; 静态同步函数使用的锁是该函数所属字节码文件对象; 可以使用 getClass() 的方法获取

Java多线程

人盡茶涼 提交于 2020-01-13 00:48:13
1.多线程 Thread类是Java中一个非常重要的类,它是Java多线程的基础,其他多线程如Runnable…都依赖于Thread。想要实现多线程,就必须让对象extends Thread类或者implements Runnable接口,并且复写run方法,在run方法体中完成对于业务逻辑的调用。在主线程中通过调用多线程对象的start()方法完成多线程。 2.线程的声明周期 3.Java中的多线程线程同步工具 1>synchronized关键词 非常简单粗暴的实现,只要对于某一个对象或者摸个静态方法前加上synchronized关键字,当线程调用对象或者方法时,它就会拥有这个对象的锁,其他对象无法使用对象或者调用方法,实际实践中,被当成锁的对象在方法体中最好不要进行其他操作,以免对于该对象的锁失去意义。 2>锁和可重入锁 普通锁的调用如下: synchronized ( lock ) //获得对锁的占有 { lock . wait ( ) ; //暂时释放对锁的占有,这是其他对象通过竞争获得锁,并执行自己的方法,然后归还锁。 doSometing ; lock . notify ( ) ; //方法调用结束,释放对锁的占有 } 可重入锁的调用如下: lock . lock ( ) //获得对锁的占有 Contional . await ( ) ; //暂时释放对锁的占有

Synchronized Method In Spring MVC

泄露秘密 提交于 2020-01-12 18:46:48
问题 I am attempting to use synchronize method in spring controller. Because our Payment gateway hits method [@RequestMapping(value="/pay",method=RequestMethod.POST)] different transactions [txn id : txn01 & txn02] at a time. But these 2 different transaction processing one by one than parallel due to using synchronize block. Problem -> Why i am using synchronize block in controller is that say Transaction [txn01] hits [@RequestMapping(value="/pay",method=RequestMethod.POST)] twice like duplicate

Java并发编程之volatile关键字

*爱你&永不变心* 提交于 2020-01-12 17:01:56
  大概是因为项目、业务的原因,工作上几乎还没有使用过多线程相关的功能,相关知识差不多都忘了,所以最近补一下基础。   volatile用来修饰共享变量,volatile变量具有 synchronized 的可见性特性,但是不具备原子特性。volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。当成员变量发生变化时,强迫线程将变化值回写到共享内存。以保证在同一时刻,不同的线程看到该成员变量的值是一致的。   因为volatile关键字与Java的内存模型有关,所以先看一下Java内存模型里面的几个概念知识。    1、可见性    指多个线程访问同一个变量时,一个线程修改了该变量的值,其他线程立马可以看到该线程修改后的值。   如下图所示,每个线程都有自己的工作内存,线程访问共享变量时,会先将变量加载到工作内存(如工作内存未缓存该变量),然后对工作内存中的变量副本进行读写操作。假设多个线程同时访问a变量,线程1修改了工作内存中的a变量值,但没有刷新到主内存中,其他线程从主内存缓存的a变量值还是原来的旧值;或者线程1修改a变量的值后刷新到了主内存,但是其他线程工作内存中缓存了线程1修改之前的旧值,其他线程访问该变量时没有从主内存中重新获取,就会出现在多个线程中,同一共享变量的值不一致,即存在可见性问题。   在 Java 中 volatile

Spring @Transactional with synchronized keyword doesn't work

廉价感情. 提交于 2020-01-12 07:51:11
问题 Let's say I have a java class with a method like this (just an example) @Transactional public synchronized void onRequest(Request request) { if (request.shouldAddBook()) { if (database.getByName(request.getBook().getName()) == null) { database.add(request.getBook()); } else { throw new Exception("Cannot add book - book already exist"); } } else if (request.shouldRemoveBook()) { if (database.getByName(request.getBook().getName()) != null) { removeBook(); } else { throw new Exception("Cannot