synchronized的使用
概念:
是利用锁的机制来实现同步的。
锁机制有如下两种特性:
互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。
可见性:必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。
为什么要使用synchronized:
在并发编程中存在线程安全问题,主要原因有:
1.存在共享数据
2.多线程共同操作共享数据。
synchronized的作用:
关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchronized可以保证一个线程的变化可见(可见性),即可以代替volatile。synchronized的用法:
1.普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁
public class synchronizedTest implements Runnable {
static synchronizedTest instance=new synchronizedTest();
static int i=0;
@Override
public void run() {
//省略其他耗时操作....
//使用同步代码块对变量i进行同步操作,锁对象为instance
synchronized(instance){
for(int j=0;j<10000;j++){
i++;
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(instance);
Thread t2=new Thread(instance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}
2.静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁
(1) 同步非静态方法
//修饰非静态方法 //代码块1(对象)this指的是当前对象
public void accessResources1(){
synchronized(this){
try {
synchronized (this){
TimeUnit.MINUTES.sleep(2);
}
System.out.println(Thread.currentThread().getName()+" is runing");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} //代码块1(CLASS类)
public void accessResources4(){
synchronized(SynchroDemo01.class){//ClassLoader class ——-》堆 Class 所有的对象
//有Class对象的所有的对象都共同使用这一个锁
try {
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+" is runing");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
final SynchroDemo01 deno01=new SynchroDemo01();
for (int i = 0; i < 5; i++) {
new Thread(deno01::accessResources1).start();
}
}
(2) 同步静态方法
public class synchronizedTest implements Runnable {
//共享资源
static int i =0;
/**
* synchronized 修饰实例方法
*/
public static synchronized void increase(){
i++;
}
@Override
public void run(){
for (int j =0 ; j<10000;j++){
increase();
}
} public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new synchronizedTest());
Thread t2 = new Thread(new synchronizedTest());
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
根据获取的锁分类:
synchronized从锁的是谁的维度一共有两种情况:
锁住类
锁住对象实例
1)静态方法上的锁
静态方法是属于“类”,不属于某个实例,是所有对象实例所共享的方法。也就是说如果在静态方法上加入synchronized,那么它获取的就是这个类的锁,锁住的就是这个类。
2)实例方法(普通方法)上的锁
实例方法并不是类所独有的,每个对象实例独立拥有它,它并不被对象实例所共享。这也比较能推出,在实例方法上加入synchronized,那么它获取的就是这个累的锁,锁住的就是这个对象实例。
那锁住类还是锁住对象实例,
synchronized的使用的更多相关文章
- java 多线程 Synchronized方法和方法块 synchronized(this)和synchronized(object)的理解
synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块. 1. synchronized 方法:通过在方法声明中加入 synchronized ...
- 单例模式中用volatile和synchronized来满足双重检查锁机制
背景:我们在实现单例模式的时候往往会忽略掉多线程的情况,就是写的代码在单线程的情况下是没问题的,但是一碰到多个线程的时候,由于代码没写好,就会引发很多问题,而且这些问题都是很隐蔽和很难排查的. 例子1 ...
- Thread 学习记录 <1> -- volatile和synchronized
恐怕比较一下volatile和synchronized的不同是最容易解释清楚的.volatile是变量修饰符,而synchronized则作用于一段代码或方法:看如下三句get代码: int i1; ...
- synchronized使用说明
好久没有更新博客了,今天试着用简单的语言把synchronized的使用说清楚. synchronized是什么? synchronized是用来保证在多线程环境下代码同步执行的可重入的互斥锁.所谓互 ...
- 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition
img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...
- (转)Lock和synchronized比较详解
今天看了并发实践这本书的ReentantLock这章,感觉对ReentantLock还是不够熟悉,有许多疑问,所有在网上找了很多文章看了一下,总体说的不够详细,重点和焦点问题没有谈到,但这篇文章相当不 ...
- Synchronized同步性与可见性
Synchronized是具有同步性与可见性的,那么什么是同步性与可见性呢? (1)同步性:同步性就是一个事物要么一起成功,要么一起失败,可谓是有福同享有难同当,就像A有10000去银行转5000给身 ...
- 基于synchronized 或 ReadWriteLock实现 简单缓存机制
package cn.xxx.xxx; import java.util.HashMap; import java.util.Map; import java.util.concurrent.lock ...
- 【Java并发编程实战】-----synchronized
在我们的实际应用当中可能经常会遇到这样一个场景:多个线程读或者.写相同的数据,访问相同的文件等等.对于这种情况如果我们不加以控制,是非常容易导致错误的.在java中,为了解决这个问题,引入临界区概念. ...
- Lock、ReentrantLock、synchronized、ReentrantReadWriteLock使用
先来看一段代码,实现如下打印效果: 1 2 A 3 4 B 5 6 C 7 8 D 9 10 E 11 12 F 13 14 G 15 16 H 17 18 I 19 20 J 21 22 K 23 ...
随机推荐
- NetBIOS 计算机名称命名限制
本文告诉大家对于 NetBIOS 的命名的限制 长度限制 最小长度是 1 最长长度是 15 因为默认是 16 字符,但是微软使用最后一个字符作为后缀 可以使用的字符 可以使用英文和数字 abcdefg ...
- codeforces 1165F1/F2 二分好题
Codeforces 1165F1/F2 二分好题 传送门:https://codeforces.com/contest/1165/problem/F2 题意: 有n种物品,你对于第i个物品,你需要买 ...
- c++修改系统环境变量 (修改注册表以后,立刻使用SendMessageTimeout(HWND_BROADCAST进行广播)
#include "stdafx.h" #include "addPath.h" #define _AFXDLL #include <afxwin.h&g ...
- hadoop常用端口及定义方法
hadoop2.x常用到的组件:HDFS, YARN, HBase, Hive, ZooKeeper: 组件 节点 默认端口 配置 用途说明HDFS DataNode 50010 dfs.datano ...
- 异步加载css 和 谷歌浏览器各实用小工具介绍
异步加载css资源 加开页面首屏显示速度使我们前端一直在追求的目标,而css资源在这些优化中同样也是不可或缺的. 一个网站可能有一部分css资源是必须的,他需要在页面渲染完之前就被加载完,并和html ...
- Python网络编程笔记二
使用select模块实现IO多路复用服务端 import socket import select #windows上只支持select.select,不支持poll epoll HOST = &qu ...
- 第二阶段:4.商业需求文档MRD:6.PRD-其他需求
- 使用windows api函数捕获SAP session的左下角消息句柄
背景:SAP session的左下角消息非常有用,我们在做SAP的自动化脚本时可以设法读到这个消息的内容,作为程序后续动作的判断条件.如下图: 比如小爬之前给财务的同事制作了一个批量导出 ...
- 2019 ICPC南昌网络赛 B题
英雄灭火问题忽略了一点丫 一个超级源点的事情,需要考虑周全丫 2 #include<cstdio> #include<cstring> #include<queue> ...
- linux-head、tail、sort、uniq、pstree、ps
1.head 默认查看文件前10行 head -7 /etc/yum.conf -n num -n7代表查看文件前7行 2.tail 默认查看文件的后10行 tail -7 /etc/yum.conf ...