synchronized(同步)关键字

修饰方法

  1. 修饰普通方法,锁的是当前实例对象
  2. 修饰静态方法,锁的是当前类的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){}}

获取关于类的对象

  1. 类名.class
  2. 对象的引用.getClass

如果加锁失败,会怎么办?

(会触发线程调度隐含着必须执行操纵系统的代码才能完成这个工作,所有会有切换内核态的操作)

  1. 加锁失败之后没有资格继续执行代码
  2. 占据CPU没有意义
  3. 会触发线程调度,加锁失败的线程,会被调度器从CPU上调度下来
  4. 在锁打开之前,再分配CPU给该线程也没有意义
  5. 线程状态要变化(不是RUNNABLE)
  6. 线程状态编程BLOCKED(这个状态是专为sychronized加锁失败设置的专用状态)
  7. 为了准备好当锁释放时能找到该线程,把它叫回, 把线程加到这把锁的阻塞队列中(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能保护什么,起到什么作用

  1. 原子性
  2. 内存可见性(sychronized加锁成功之后,必须做一次从主内存到工作内存得同步操作,保证线程看到的是最新的数据。释放锁之后,必须做一次从工作内存到主内存的刷新操作,保证所有最新的数据写回主内存。用了该关键字也不能保证一定会有同步操作)
  3. 代码有序性
    加锁前的一些语句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关键字的用法相关推荐

  1. java中的同步关键字_Java中进程同步问题,锁 和synchronized 关键字的用法

    标签: •对象的锁标志 –每个对象都有一个锁标志 –使用synchronized可与锁标志交互 •synchronized关键字的用法有两种: –synchronized语句 –synchronize ...

  2. 多线程,线程同步,synchronized关键字的用法

    一.什么是多线程 Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorSe ...

  3. Synchronized 关键字的用法

    第一条:当一个线程访问某对象的synchronized方法或者synchronized代码块时,其他线程对该对象的该synchronized方法或者synchronized代码块的访问将被阻塞. pu ...

  4. Java 多线程(六) synchronized关键字详解

    多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同步用以解决多个线程同时访问时可能出现的问题. 同步机制可以使用synchronized关键字实现. 当synchroniz ...

  5. java线程同步以及对象锁和类锁解析(多线程synchronized关键字)

    一.关于线程安全 1.是什么决定的线程安全问题? 线程安全问题基本是由全局变量及静态变量引起的. 若每个线程中对全局变量.静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的:若有多个线 ...

  6. java同步锁synchronized_Java对象锁和类锁全面解析(多线程synchronized关键字)

    本文主要是将synchronized关键字用法作为例子来去解释Java中的对象锁和类锁.特别的是希望能帮大家理清一些概念. 一.synchronized关键字 synchronized关键字有如下两种 ...

  7. java中存在对多个对象加锁的情况_Java对象锁和类锁全面解析(多线程synchronized关键字)...

    最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不过是别人怎么用就跟着用,并没有搞清楚锁的概念.最近也是遇到一些问题,不搞清楚锁的概念,很容易碰壁,甚至有些时候自己连用没 ...

  8. Java对象锁和类锁全面解析(多线程synchronized关键字)

    最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不过是别人怎么用就跟着用,并没有搞清楚锁的概念.最近也是遇到一些问题,不搞清楚锁的概念,很容易碰壁,甚至有些时候自己连用没 ...

  9. Java 对象锁和类锁 死锁(多线程synchronized关键字)

    本文主要是将synchronized关键字用法作为例子来去解释Java中的对象锁 和 类锁. 对于同步,要时刻清醒在 哪个锁对象 上同步,这是关键. 对于同步代码块,要看清楚什么对象已经用于锁定(sy ...

最新文章

  1. 《iOS应用软件设计之道》—— 3.1 流向:从一个画面到另一个画面
  2. wordpressPHP实现ajax评论,AJAX_wordpress 为主题添加AJAX提交评论功能的php代码,首先需要在主题的function.php文 - phpStudy...
  3. 解决spring配置c3p0连接池,tomcat无法正常启动
  4. 异步生成器_异步生成器作为状态管理的替代方法
  5. python 元类 详解_Python 元类详解 __new__、__init__、__call__、__metacalss__
  6. 小学python还是c_python和c先学哪个
  7. 使用trycatch获取异常问题
  8. 数据绑定表达式语法(Eval,Bind区别)
  9. 【Linux】高效快速的指令:linux磁盘管理、vi、sed、find、grep、awk等
  10. 转四种常见的post请求
  11. 鼠标悬停显示不同内容_数字标牌的A到Z:C代表CMS(内容管理系统)
  12. 【数据压缩(十)】H264文件分析2
  13. 网络流(最大流)基础入门
  14. y480 linux无线网卡驱动,联想y480无线网卡驱动下载-联想y480笔记本网卡驱动v15.0.0.75 官方版 - 极光下载站...
  15. 企业进销存管理系统(一)
  16. 2020国内学者SCIENCE发文盘点,生物类 37 篇 (新冠相关 9 篇)
  17. module ‘statsmodels.stats.diagnostic‘ has no attribute ‘het_breushpagan‘
  18. 365天口才训练计划
  19. QQ空间|qq人气号怎么赚钱?
  20. 谷歌浏览器收藏栏不见了解决办法

热门文章

  1. hive入门之安装模式
  2. mysql填写账户远程_如何开启MySQL的远程帐号
  3. orbeon form 的日志处理
  4. jMeter Transaction Controller 学习笔记
  5. SAP Spartacus 中的 HTML 标签
  6. ng-content的一个实际例子
  7. 一个关于Angular Directive selector里的中括号使用问题
  8. SAP Spartacus键盘按下tab键之后,出现的focus state border是如何实现的
  9. SAP ABAP ADBC和Java JDBC的使用比较
  10. Gradle标准project属性