一定要会的synchronized关键字的用法
synchronized(同步)关键字
修饰方法
- 修饰普通方法,锁的是当前实例对象
- 修饰静态方法,锁的是当前类的Class对象
修饰代码块,锁的是synchronized括号里的对象
public class SyncDemo1 {//修饰普通方法public synchronized void method(){}//修饰静态方法public static synchronized void staticMethod(){}public void someMethod(){//同步代码块//这里o是局部变量,外部不可能拿到,这种加锁是毫无意义的Object o = new Object();synchronized (o){//o这个引用不能为null}}}
synchronized是如何实现加锁的?-----以同步代码块为例
java中的所有对象在jvm实现的时候,内部都包含一把锁,这把锁默认情况下是打开的。
对象可以调用getClass()方法从对象拿到该对象的“类对象”。
同步代码块的理解
synchronized(ref){//加锁一些语句;//加锁成功才能执行
}//释放锁
普通同步方法的理解
//修饰普通方法public synchronized void method(){}//效果同上public void method1(){synchronized (this){}}
静态同步方法的理解
//修饰静态方法public static synchronized void staticMethod(){}//效果同上public void staticMethod1(){synchronized (SyncDemo1.class){}}
获取关于类的对象
- 类名.class
- 对象的引用.getClass
如果加锁失败,会怎么办?
(会触发线程调度隐含着必须执行操纵系统的代码才能完成这个工作,所有会有切换内核态的操作)
- 加锁失败之后没有资格继续执行代码
- 占据CPU没有意义
- 会触发线程调度,加锁失败的线程,会被调度器从CPU上调度下来
- 在锁打开之前,再分配CPU给该线程也没有意义
- 线程状态要变化(不是RUNNABLE)
- 线程状态编程BLOCKED(这个状态是专为sychronized加锁失败设置的专用状态)
- 为了准备好当锁释放时能找到该线程,把它叫回, 把线程加到这把锁的阻塞队列中(blocking queue)
易错点
哪些情况下会导致两个线程之间产生互斥
public class SyncDemo2 {//没加锁void method1() {}//锁的时synchronized void method2() {}static synchronized void method3() {}void method4() {synchronized (this) {}}static void method5() {synchronized (SyncDemo2.class) {}}void method6() {synchronized (SyncDemo2.class) {}}}
改造n++和n–操作,使得线程安全
只要保证同时加锁,加得是同一把锁,哪个对象都可以
锁得粒度会影响运行效率。
class Adder extends Thread{Object o = new Object();Adder(Object o){this.o = o;}@Overridepublic void run() {synchronized (o) {for (long i = 0; i < 100_0000_0000L; i++) {ThreadDemo.n++;}}}
}class Suber extends Thread{Object o = new Object();Suber(Object o){this.o = o;}@Overridepublic void run() {synchronized (o) {for (long i = 0; i < 100_0000_0000L; i++) {ThreadDemo.n--;}}}
}
public class ThreadDemo {static int n = 0;public static void main(String[] args) throws InterruptedException {Object o = new Object();Thread a = new Adder(o);Thread b = new Suber(o);a.start();b.start();a.join();b.join();System.out.println(n);}}
当线程A在操作访问锁定的对象时候, 线程B如果要进入synchronized代码块执行的时候是必须等待锁释放的。这样实际上就是将原本并行执行的代码,变为串行执行了。
sychronized能保护什么,起到什么作用
- 原子性
- 内存可见性(sychronized加锁成功之后,必须做一次从主内存到工作内存得同步操作,保证线程看到的是最新的数据。释放锁之后,必须做一次从工作内存到主内存的刷新操作,保证所有最新的数据写回主内存。用了该关键字也不能保证一定会有同步操作)
- 代码有序性
加锁前的一些语句A
加锁部分的一些语句B
加锁后的一些语句C
创建一个线程安全的ArrayList
单线程下不建议使用Vector,因为Vector无脑给所有方法都加锁了,单线程下会有很多加锁和释放锁的操作来耗费时间。
public class ArrayList {private int size;private final long[]array = new long[100];public synchronized void add(long e){array[size++] = e;}public synchronized int size(){return size;}public synchronized long get(int index){if (index > 0 || index >= size){throw new ArrayIndexOutOfBoundsException();}return array[index];}
}
一定要会的synchronized关键字的用法相关推荐
- java中的同步关键字_Java中进程同步问题,锁 和synchronized 关键字的用法
标签: •对象的锁标志 –每个对象都有一个锁标志 –使用synchronized可与锁标志交互 •synchronized关键字的用法有两种: –synchronized语句 –synchronize ...
- 多线程,线程同步,synchronized关键字的用法
一.什么是多线程 Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorSe ...
- Synchronized 关键字的用法
第一条:当一个线程访问某对象的synchronized方法或者synchronized代码块时,其他线程对该对象的该synchronized方法或者synchronized代码块的访问将被阻塞. pu ...
- Java 多线程(六) synchronized关键字详解
多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同步用以解决多个线程同时访问时可能出现的问题. 同步机制可以使用synchronized关键字实现. 当synchroniz ...
- java线程同步以及对象锁和类锁解析(多线程synchronized关键字)
一.关于线程安全 1.是什么决定的线程安全问题? 线程安全问题基本是由全局变量及静态变量引起的. 若每个线程中对全局变量.静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的:若有多个线 ...
- java同步锁synchronized_Java对象锁和类锁全面解析(多线程synchronized关键字)
本文主要是将synchronized关键字用法作为例子来去解释Java中的对象锁和类锁.特别的是希望能帮大家理清一些概念. 一.synchronized关键字 synchronized关键字有如下两种 ...
- java中存在对多个对象加锁的情况_Java对象锁和类锁全面解析(多线程synchronized关键字)...
最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不过是别人怎么用就跟着用,并没有搞清楚锁的概念.最近也是遇到一些问题,不搞清楚锁的概念,很容易碰壁,甚至有些时候自己连用没 ...
- Java对象锁和类锁全面解析(多线程synchronized关键字)
最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不过是别人怎么用就跟着用,并没有搞清楚锁的概念.最近也是遇到一些问题,不搞清楚锁的概念,很容易碰壁,甚至有些时候自己连用没 ...
- Java 对象锁和类锁 死锁(多线程synchronized关键字)
本文主要是将synchronized关键字用法作为例子来去解释Java中的对象锁 和 类锁. 对于同步,要时刻清醒在 哪个锁对象 上同步,这是关键. 对于同步代码块,要看清楚什么对象已经用于锁定(sy ...
最新文章
- 《iOS应用软件设计之道》—— 3.1 流向:从一个画面到另一个画面
- wordpressPHP实现ajax评论,AJAX_wordpress 为主题添加AJAX提交评论功能的php代码,首先需要在主题的function.php文 - phpStudy...
- 解决spring配置c3p0连接池,tomcat无法正常启动
- 异步生成器_异步生成器作为状态管理的替代方法
- python 元类 详解_Python 元类详解 __new__、__init__、__call__、__metacalss__
- 小学python还是c_python和c先学哪个
- 使用trycatch获取异常问题
- 数据绑定表达式语法(Eval,Bind区别)
- 【Linux】高效快速的指令:linux磁盘管理、vi、sed、find、grep、awk等
- 转四种常见的post请求
- 鼠标悬停显示不同内容_数字标牌的A到Z:C代表CMS(内容管理系统)
- 【数据压缩(十)】H264文件分析2
- 网络流(最大流)基础入门
- y480 linux无线网卡驱动,联想y480无线网卡驱动下载-联想y480笔记本网卡驱动v15.0.0.75 官方版 - 极光下载站...
- 企业进销存管理系统(一)
- 2020国内学者SCIENCE发文盘点,生物类 37 篇 (新冠相关 9 篇)
- module ‘statsmodels.stats.diagnostic‘ has no attribute ‘het_breushpagan‘
- 365天口才训练计划
- QQ空间|qq人气号怎么赚钱?
- 谷歌浏览器收藏栏不见了解决办法