一.synchronized

1.synchronized使用的方法

  • 可以直接修饰代码块
synchronized (this) {
//代码块
}
  • 调用可能出现并发问题的方法
synchronized (this) {
method();
}
  • 修饰方法
public synchronized void method() {
//...
}

2.注意

当synchronized修饰方法时:

  • 非静态方法中,synchronized锁当前对象:this
  • 静态方法中,synchronized锁的是当前类的字节码对象User.class

3.不要以字符串作为锁的对象

  • 有如下代码
String s1 = "hello";
String s2 = "hello"; void m1() {
synchronized (s1) {
}
}
void m2() {
synchronized (s2) {
}
}
  • 因为s1s2的创建都使用的是直接赋值,此时的hello会创建在常量池中,实际上s1s2都指向的是同一个对象,被s1、s2引用。
  • 所以,此时的synchronized (s1)synchronized (s2)实际上锁的都是同一个对象。
  • 因此,使用synchronized锁的时候最好不要锁字符串类型。
  • 如果非要锁字符串,那么使用new String ("hello")的方法来创建字符串,因为这样创建出来的字符串就是两个堆内存中的对象了。

4.synchronized锁的是什么?

  • synchronized锁的是堆内存中new出来的对象,而不是栈中的引用。

二、volatile

1.引出问题

两个线程操作同一个主存数据时,会先将主存中的数据复制到自己的内存区域,将数据修改后,再写回主存。


两线程同时复制到自己内存后:

  • 线程1将数据修改a=1后,写回主存
  • main线程很忙,一直在进行while(true) 循环,没有时间再去主存中读取新的数据,所以main线程缓存中的数据还是a=0
  • 为了解决这个问题,就引出了volatile

2. volatile使用方法

  • 直接将volatile关键字加在要操作的数据上
private volatile int a = 0;

3.volatile原理

  • 线程1将数据修改后,会通知main线程:“你的数据已经过期了”
  • 此时main线程会从主存中重新读取新的数据
  • 这也就是volatile三个特性的-保证可见性

4.volatile三大特性

  • 保证可见性
  • 不保证原子性
  • 禁止指令重排

三、volatile和synchronized的区别

1.区别

  • volatile是轻量级的,synchronized是是重量级的
  • volatile保证内存可见性,而不保证原子性(解决此问题的办法:就是使用原子数据)
  • synchronized既保证内存可见性,也保证原子性

2.解决原子性问题–原子型数据类型

  • java.util.concurrent.atomic包下,有基本数据类型对应的原子型的数据类型,类似于基本数据类型的包装类型。

3.让对象类型数据具有原子型

  • 还是在java.util.concurrent.atomic包下,有一个类,可以使对象类型的数据具有原子性:AtomicReference
//创建两个对象
User zhangsan = new User("zhangsan");
User sili = new User("sili");
//创建原子操作对象
AtomicReference<User> atomicReference = new AtomicReference<User>();
//比较并交换
boolean b = atomicReference.compareAndSet(zhangsan, sili);
System.out.println(b);

【java多线程】synchronized和volatile的更多相关文章

  1. Java 多线程 —— synchronized关键字

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  2. java多线程中的volatile和synchronized

    package com.chzhao; public class Volatiletest extends Thread { private static int count = 0; public ...

  3. Java多线程系列八——volatile和ThreadLocal

    参考资料: http://ifeve.com/java-memory-model-4/ http://www.infoq.com/cn/articles/java-memory-model-1 htt ...

  4. java多线程4:volatile关键字

    上文说到了 synchronized,那么就不得不说下 volatile关键字了,它们两者经常协同处理多线程的安全问题. volatile保证可见性 那么volatile的作用是什么呢? 在jvm运行 ...

  5. Java多线程synchronized同步

    非线程安全问题 “非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程问题”.也即是说,方法中的变量永远是线程安全的. 如果多个线程共同访问1个对象中的实例变量,则可能线程 ...

  6. Java 线程 — synchronized、volatile、锁

    线程同步基础 synchronized 和volatile是Java线程同步的基础. synchronized 将临界区的内容上锁,同一时刻只有一个进程能访问该临界区代码 使用的是内置锁,锁一个时刻只 ...

  7. JAVA多线程synchronized详解

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当两个并发线程访问同一个对象object中的这个synchronized(this)同 ...

  8. java 多线程11:volatile关键字

    直接先举一个例子普通的线程实例变量的非可见性: public class MyThread28 extends Thread { private boolean isRunning = true; p ...

  9. java多线程-synchronized

    一.线程安全问题 多线程操作各自线程创建的资源的时候,不存在线程安全问题.但多线程操作同一个资源的时候就会出现线程安全问题.下例为两个线程操作同一个name资源时发生的问题. class TestSy ...

  10. Java多线程 -- 正确使用Volatile变量

    Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”:与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少, ...

随机推荐

  1. GO Exit Fatal panic

    Exit() 应用程序(不只是函数)退出执行 defer 不会被执行(因为程序都退出了) log.Fatal() 输出打印内容 应用程序退出 defer 不会被执行 panic() 函数停止执行(不是 ...

  2. Output of C++ Program | Set 12

    Predict the output of following C++ programs. Question 1 1 #include <iostream> 2 using namespa ...

  3. java内存管理的小技巧

    1,尽量使用直接量.     采用String str="hello"; 而不是 String str = new String("hello"): 2,使用S ...

  4. GO类型转换

    golang []byte转string golang中,字符切片[]byte转换成string最简单的方式是 package main import ( "fmt" _ &quo ...

  5. 创建线程的第二种方式------实现Runnable接口的方式

    package cn.itcast.demo16.Demo07.Runnable;/** * @author newcityman * @date 2019/7/22 - 23:17 */public ...

  6. I/O流之文件流

    1.文件操作类 File 1.public File(String pathname)//给定一个要操作文件的完整路径 2.public File(File parent,String child)/ ...

  7. Rust开发环境搭建和hello world工程

    windows10 WSL 打开wsl,执行以下命令 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 出现安装选项,选择1 ...

  8. View的简单说明

    一)三个结构体:CGPoint.CGSize.CGRect 1. CGPoint struct CGPoint { CGFloat x; CGFloat y; }; typedef struct CG ...

  9. 图数据库HugeGraph:HugeGraph-Hubble基于Web的可视化图管理初体验

    原创/朱季谦 一.HugeGraph-Hubble简介 关于HugeGraph,官方资料是这样介绍的,它是一款易用.高效.通用的开源图数据库系统(Graph Database), 实现了 Apache ...

  10. 铁人三项(第五赛区)_2018_rop

    拿到程序依旧老样子checksec和file一下 可以看到是32位的程序开启了nx保护,将程序放入ida进行查看 shift+f12 看到没有system和binsh等字样,考虑用泄露libc来做这道 ...