精华内容
下载资源
问答
  • synchronized volatile

    2019-08-20 14:50:09
    synchronizedvolatile 关键字的作用

    synchronized:

    Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。
    使用方法:
    方式一:同步代码块
    synchronized(对象锁){//常用锁:this和类名.class
    }
    方式二:同步方法,默认锁为this
    方式三:同步静态方法,默认锁为类名.class

    //sleep 释放cpu执行权,不主动释放锁
    public class Task implements Runnable {
    	static int ticket = 5;
    
    	@Override
    	public void run() {// 线程任务,可以被多个线程对象同时来启动
    		for (int i = 0; i < 100; i++) {
    			try {
    				Thread.sleep(5000);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			synchronized ("a") {// 每次只允许一个线程进入
    
    				if (ticket > 0) {
    					System.out.println(Thread.currentThread() + "--同步代码块卖票--" + ticket--);
    				}
    			} // 下一个线程必须等待上一个线程结束该同步
    		}
    	}
    
    	// 同步方法:this
    	public synchronized void sell() {
    
    		if (ticket > 0) {
    			System.out.println(Thread.currentThread() + "--同步方法卖票--" + ticket--);
    		}
    
    	}
    
    	// 同步静态方法:类名.class
    	public static synchronized void sell2() {
    		if (ticket > 0) {
    			System.out.println(Thread.currentThread() + "--卖票--" + ticket--);
    		}
    
    	}
    }
    
    

    同步注意事项:
    (1)代码尽量简短。
    (2)不要阻塞。
    (3)“死锁”: 在持有锁的时候,不要对其它对象调用方法;锁之间不要互相调用。

    volatile

    并发编程的3个基本概念
    (1)原子性
    即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
    (2)可见性
    定义:指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
    (3)有序性
    定义:即程序执行的顺序按照代码的先后顺序执行。

    1.作用:保证被volatile修饰的共享变量的可见性 & 有序性,但不保证原子性
    2.弥补volatile关键字的原子性
    (1)synchronized 是不太可控的锁,隐式锁
    (2)在JDK1.5以后,出现了Lock,显示锁
    (3)在java 1.5的java.util.concurrent.atomic包下提供了一些原子操作类,即对基本数据类型的 自增(加1操作),自减(减1操作)、以及加法操作(加一个数),减法操作(减一个数)进行了封装,保证这些操作是原子性操作。
    3.使用:通常是初始化工作,进行读取多,写入少的操作

    public class VolatileTest0 {
    	// 加上volatile 修饰的是时候,程序会很快退出,因为volatile
    	// 保证各个线程工作内存的变量值和主存一致。所以boolValue == !boolValue就成为了可能。
    	volatile boolean boolValue;
    
    	/**
    	 * 成员变量boolValue使用volatile和不使用volatile会有明显区别的。 本程序需要多试几次,就能知道两者之间的区别的。
    	 * t1和t2两个线程启动后,程序可能结束,可能不结束
    	 * 
    	 */
    	public static void main(String[] args) {
    
    		final VolatileTest0 volObj = new VolatileTest0();
    		// 利用匿名内部类开启了两个线程
    		Thread t1 = new Thread() {
    			public void run() {
    				System.out.println("t1 start");
    				for (;;) {
    					volObj.waitToExit();
    				}
    			}
    		};
    		t1.start();
    		Thread t2 = new Thread() {
    			public void run() {
    				System.out.println("t2 start");
    				for (;;) {
    					volObj.swap();
    				}
    			}
    		};
    		t2.start();
    	}
    
    	public void waitToExit() {
    		if (boolValue == !boolValue)
    			System.exit(0);// 非原子操作,理论上应该很快会被打断。实际不是,因为此时的boolValue在线程自己内部的工作内存的拷贝,因为它不会强制和主存区域同步,线程2修改了boolValue很少有机会传递到线程一的工作内存中。所以照成了假的“原子现象”。
    	}
    
    	public void swap() {// 不断反复修改boolValue,以期打断线程t1.
    		boolValue = !boolValue;
    	}
    }
    
    
    public class VolatileTest1 {
    	public volatile int inc = 0;
    
    	public void increase() {
    		// 对该变量读取,对该变量++,对该变量赋值,这是一个原子性操作
    		inc++;// 满足原子性?
    	}
    
    	public static void main(String[] args) {
    		final VolatileTest1 test = new VolatileTest1();
    		for (int i = 0; i < 10; i++) {
    			new Thread() {
    				public void run() {
    					for (int j = 0; j < 1000; j++)
    						test.increase();
    				};
    			}.start();
    		}
    
    		while (Thread.activeCount() > 1) // 保证前面的线程都执行完
    			Thread.yield();
    		System.out.println(test.inc);// 会出现小于10000的情况,volatile不保证原子性
    	}
    }
    
    
    展开全文
  • Synchronized与 Volatile

    2021-06-16 19:59:29
    Synchronized 原子性、可见性 synchronied 块是 Java 提供的一种原子性内置锁, Jav 中的每个对象都可以把它当作一个同步锁来使用 这些 Java 内置的使用者看不到的锁被称为内部锁,也称作监视器锁。线程进入...

    Synchronized
    原子性可见性
    synchronied 块是 Java 提供的一种原子性内置锁, Jav 中的每个对象都可以把它当作一个同步锁来使用 这些 Java 内置的使用者看不到的锁被称为内部锁,也称作监视器锁。线程进入synchronized后自动获取内部锁,这时候其他线程来就会阻塞挂起,必须等到synchronized释放锁后才能重新获得锁。
    synchronized保证了原子性、内存可见性(因为它使用到的变量不会从工作内存中取,而是直接从主存中获取,退出syn块的内存语义就是把syn块内对共享变量的修改刷新到主存,所以保证了内存可见性)。
    缺点:会引起频繁的上下文切换。带来线程调度的开销。

    Volatile
    提供了 可见性有序性(禁止指令重排序)
    用syn解决可见性使用锁比较笨重,java还提供了一种弱形式的同步volatile。volatile确保对一个变量的更新直接对其他线程立马可见,当一个变量声明为volatile时,线程写入时不会吧值缓存在寄存器或其他地方,而是直接刷新到主存。其他线程读取也是直接取主存。具体来说线程写入volatile相当于syn退出,因为都会吧数据刷新到主存。

    展开全文
  • synchronized与volatile

    2020-11-12 18:01:27
    # synchronized - synchronized介绍 在《Java并发编程之美》中介绍:`synchronized`块是Java提供的一种原子性内置锁,Java中的每个对象都可以把它当作一个同步锁来使用,这些Java内置的使用者看不到的锁被称为内部...

    synchronized

    • synchronized介绍

    在《Java并发编程之美》中介绍:`synchronized`块是Java提供的一种原子性内置锁,Java中的每个对象都可以把它当作一个同步锁来使用,这些Java内置的使用者看不到的锁被称为内部锁,也叫作监视器锁。

    线程进入到`synchronized`中时会自动获取内置锁,这时其他线程访问该代码块时会被挂起,直到锁释放。

    • synchronized内存语义

    每个线程都用自己的工作内存,当多个线程操作同一个变量时,就会出现某个线程对变量的修改,其他线程并不能马上知道,这时候其他线程操作的这个变量就可能是修改前的值,这个就是共享变量内存可见性可见性问题。而使用`synchronized`可以解决这个问题。

    《Java并发编程之美》:进入`synchronized`块的内存语义是把在`synchronized`块内使用到的变量从线程的工作内存中清除,这样在synchronized块内使用到该变量时就不会从线程的工作内存中获取,而是直接从主内存中获取。退出synchronized块的内存语义是把在`synchronized`块内对共享变量的修改刷新到主内存。

    进入`synchronized`块就相当于加锁,退出就是解锁。synchronized关键字会引起线程上下文切换并带来线程调度开销,这是很耗时的操作。

    volatile

    • volatile介绍

    `volatile`作用于变量上,当一个变量声明为volatile时,线程在写入变量时不会把值缓存在寄存器或者其他地方,而是会把值刷新回主内存。当其他线程读取该共享变量时,会从主内存重新获取最新值,而不是使用当前线程的工作内存中的值。

    展开全文
  • Synchronized与Volatile

    2017-06-08 10:16:07
    1、volatile变量是一种稍弱的同步机制在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比synchronized关键字更轻量级的同步机制。  2、从内存可见性的角度看,写入...
    
    1、volatile变量是一种稍弱的同步机制在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比synchronized关键字更轻量级的同步机制。

        2、从内存可见性的角度看,写入volatile变量相当于退出同步代码块,而读取volatile变量相当于进入同步代码块。

        3、在代码中如果过度依赖volatile变量来控制状态的可见性,通常会比使用锁的代码更脆弱,也更难以理解。仅当volatile变量能简化代码的实现以及对同步策略的验证时,才应该使用它。一般来说,用同步机制会更安全些。

        4、加锁机制(即同步机制)既可以确保可见性又可以确保原子性,而volatile变量只能确保可见性,原因是声明为volatile的简单变量如果当前值与该变量以前的值相关,那么volatile关键字不起作用,也就是说如下的表达式都不是原子操作:“count++”、“count = count+1”。

     

         当且仅当满足以下所有条件时,才应该使用volatile变量:

         1、对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值。

         2、该变量没有包含在具有其他变量的不变式中。


    总结:在需要同步的时候,第一选择应该是synchronized关键字,这是最安全的方式,尝试其他任何方式都是有风险的。尤其在、jdK1.5之后,对synchronized同步机制做了很多优化,如:自适应的自旋锁、锁粗化、锁消除、轻量级锁等,使得它的性能明显有了很大的提升。

    展开全文
  • 既生synchronized,何生volatile (synchronized与volatile的区别) 我们知道,synchronized和volatile两个关键字是Java并发编程中经常用到的两个关键字,而且,通过前面的回顾,我们知道synchronized可以保证并发...
  • 主要介绍了Synchronized与Volatile区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • synchronized与volatile异同  volatile关键字有什么用? 恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段代码或方法;看如下三句get代码: int ...
  • 线程锁(synchronized与volatile)简单地对synchronized和volatile两种锁进行总结,以便以后查找方便,希望大家提出宝贵建议,以便日后进一步完善。1.synchronized的用法:1)修饰方法的三种用法:a)public class ...
  • 一、Synchronized与Volatile的区别 首先需要理解线程安全的两个方面:执行控制和内存可见。执行控制的目的是控制代码执行(顺序)及是否可以并发执行。内存可见控制的是线程执行结果在内存中对其它线程的可见性。...
  • 导航synchronized如何使用synchronized关键字synchronized关键字的底层原理Java对象头锁升级synchronized性质volatilevolatile作用volatile底层原理二者对比 synchronized synchronized是一种同步锁,可以保证被它...
  • 并发系列之synchronized与volatile的区别1、使用上的区别2、对原子性的保证3、对可见性的保证4、对有序性的保证和阻塞5、往期佳文5.1、面试系列5.2、技术系列5.3、源码系列5.4、数据结构和算法系列5.5、多线程系列 ...
  • 本章我们介绍下Java中的Synchronized与Volatile关键字. 在本章中,我们将介绍如下的几个模块: Synchronized关键字 线程安全问题 synchronized 关键字的使用 对象锁与类锁 Synchronized关键字修饰final类型的变量 &...
  • 一文详解synchronized与volatile

    万次阅读 2020-04-28 14:55:12
    1)synchronized对象监视器为Object时的使用; 2)synchronized对象监视器为Class时的使用; 3)非线程安全是如何出现的; 4)volatile的主要作用;...5)volatile与synchronized的区别及使用情况。
  • 关键字volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且只能修改变量,而synchronized可以修饰方法,以及代码块; 多线程访问volatile不会发生阻塞,而synchronized会出现阻塞; ...
  • 在多线程并发编程中synchronizedvolatile都扮演着重要的角色,synchronized一直是元老级角色,很多人都会称呼它为重量级锁。但是,随着Java SE 1.6对synchronized进行了各种优化之后,有些情况下它就并不那么重了...
  • 文章目录SynchronizedCASCAS底层对象的内存布局synchronized锁升级过程:对象头MarkWord:加锁详解:锁消除锁粗化volatilevolatile的用途volatile实现细节内存屏障实现 Synchronized CAS 多线程的情况下,i++可能会...
  • 再说synchronized与volatile之前,先让我们了解一下CAS。 CAS(compare and swap) CAS全称为compare and swap,比较与交换。因为经常与循环一起工作时又称为自旋、自旋锁或无锁,所以泛指一类操作。 CAS具体思路为...
  • #synchronized与volatile synchronized用来实现资源利用的互斥性,被其标识的区间同一时间只允许一个线程运行。 volatile被用于设计可见性,指的是一个线程操作完一个资源后,另一个线程获取到的一定是最新的...
  • 在多线程并发编程中synchronizedvolatile都扮演着重要的角色,synchronized一直是元老级角色,很多人都会称呼它为重量级锁。但是,随着Java SE 1.6对synchronized进行了各种优化之后,有些情况下它就并不那么重了...
  • synchronized获得并释放监视器——如果两个线程...volatile只是在线程内存和“主”内存间同步某个变量的值,而synchronized通过锁定和解锁某个监视器同步所有变量的值 synchronized要比volatile消耗更多资源。 ...
  • synchronizedvolatile的区别: 一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,417
精华内容 966
关键字:

synchronized与volatile