Java同步块用来标记一个方法或一个代码块为同步的。Java同步块可以用来避免竞态。

Java同步关键字

在 Java 中使用 synchronized 来标记同步块。一个同步块是同步在某些对象上。同一个对象上的所有同步块只能有一个线程执行里面的代码。其他线程试图进入同步块都会被阻塞,直到同步块中的现成离开同步块。

synchronized 可以用来标记 4 种不同的同步块:

实例方法

静态方法

实例方法中的代码块

静态代码中的代码块

这些同步块都同步在不同的对象上。视情况去使用它。

同步的实例方法

public synchronized void add(int value) {

this.count += value;

}

一个同步实例方法是同步在拥有该方法的实例上。同步实例方法中只能有一个线程可以执行里面的方法。如果有多个实例,每个实例只能有一个线程去执行同步实例方法,也就是一个实例一个线程。

同步静态方法

public static synchronized void add(int value) {

count += value;

}

同步静态方法同步在类的类对象上。因为 JVM 中每个类只能有一个类对象。只有一个线程可以执行同一个类中的同步静态方法。

一个类只能有一个线程,不管是执行哪一个同步静态方法。

实例方法中的代码块

有时候,可以不需要把整个方法同步,可以把方法的一部分同步。比如下面的代码:一个不同步的方法中包含同步的代码块

public void add(int value) {

synchronized(this) {

this.count += value;

}

}

上面的示例代码使用同步块构造器来标记代码块是同步的。这个代码执行起来和同步方法一样。

下面的代码执行效果是一样的

public class MyClass {

public synchronized void log1(String msg1, String msg2) {

log.writeln(msg1);

log.writeln(msg2);

}

public viod log2(String msg1, String msg2) {

synchronized(this) {

log.writeln(msg1);

log.writeln(msg2);

}

}

}

如果第二个同步块不是同步在this实例对象上,那么两个方法可以被线程同时执行。

同步静态代码块

public class MyClass {

public static synchronized void log1(String msg1, String msg2) {

log.writeln(msg1);

log.writeln(msg2);

}

public static viod log2(String msg1, String msg2) {

synchronized(MyClass.class) {

log.writeln(msg1);

log.writeln(msg2);

}

}

}

这些方法都同步在类上。

如果第二个同步块不是同步在MyClass.class这个对象上。那么这两个方法可以同时被线程访问。

Java 同步代码例子

public class Counter {

long count = 0;

public synchronized void add(long value) {

this.count += value;

}

}

``java

public class CounterThread extends Thread {

protected Counter counter = null;

public CounterThread(Counter counter) {

this.counter = counter;

}

public void run() {

for (int i = 0; i < 10; i++) {

counter.add(i);

}

}

}

``java

public class Example {

public static void main(String[] args) {

Counter counter = new Counter();

Thread threadA = new CounterThread(counter);

Thread threadB = new CounterThread(counter);

threadA.start();

threadB.start();

}

}

当线程创建的时候,都传入了相同的 Counter 实例。Counter.add() 是同步实例方法。所以每次只能有一个线程可以执行该方法。另外一个线程只能等待它执行完才能去执行方法。

如果两个线程持有的不是同一个 Counter 实例的话,就不会有这个问题。

public class Example {

public static void main(String[] args) {

Counter counterA = new Counter();

Counter counterB = new Counter();

Thread threadA = new CounterThread(counterA);

Thread threadB = new CounterThread(counterB);

threadA.start();

threadB.start();

}

}

QA

Q:

如果一个对象有多个方法加了synchronized,那么该对象有几把锁?

A:

对象锁是在一个类的对象上加的的锁,只有一把,不管有几个方法进行了同步。

这些同步方法都共有一把锁,只要一个线程获得了这个对象锁,其他的线程就不能访问该对象的任何一个同步方法。

java的同步块_Java 同步块相关推荐

  1. java同步方法完成案例_Java同步代码块和同步方法原理与应用案例详解

    本文实例讲述了java同步代码块和同步方法.分享给大家供大家参考,具体如下: 一 点睛 所谓原子性WOmoad:一段代码要么执行,要么不执行,不存在执行一部分被中断的情况.言外之意是这段代码就像原子一 ...

  2. java 同步块_java 同步块(Java Synchronized Blocks)

    java 同步块(Java Synchronized Blocks) Java 同步块包括方法同步和代码块同步.java 同步可以避免资源竞争,避免死锁. 主题包括的主要内容: The Java sy ...

  3. java同步方法同步块_java 同步代码块与同步方法

    同步代码块 synchronized(obj) {//代码块 } obj 为同步监视器,以上代码的含义为:线程开始执行同步代码块(中的代码)之前,必须先获得对同步监视器的锁定. 代码块中的代码是执行代 ...

  4. java 读取 文本块_Java文本块

    java 读取 文本块 文本块是JDK增强建议( JEP 355 ),可以在JDK 13和14中用作预览语言功能.它计划在JDK 15中成为永久性功能.文本块是跨越多行并且不需要的String文字.对 ...

  5. java finally块_java finally块后的语句是否要执行

    finally快中语句肯定执行,finally块后的语句视情况而定:若是catch中截获异常或者有异常抛出,则不执行,这也不完全,例如下边的例子: package com.jessice.exampl ...

  6. java回调与异步_Java同步异步玩转回调机制

    北京这周终于凉快了不少,舒了一口气,但是中暑带来的后遗症还没减轻,晕晕乎乎地上了一周的班也不见好转,基本就是这状态: 程序员 好了,不扯了.上篇文章讲了回调的基本原理:调用方通过方法将自己身的实例传给 ...

  7. java 代码同步_Java同步代码块 转

    Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(synchronzied) 实例方法同步 静 ...

  8. java synchronized块_Java多线程同步代码块Synchronized

    Java多线程同步代码块Synchronized Java中的每个对象都有一个与之关联的内部锁(Intrinsic lock). 这种锁也称为监视器(Monitor), 这种内部锁是一种排他锁,可以保 ...

  9. java每一个小时同步_Java同步块(synchronized block)使用详解

    Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(synchronzied) 实例方法同步 静 ...

最新文章

  1. R语言dplyr包的mutate函数将列添加到dataframe中或者修改现有的数据列:使用na_if()函数将0值替换为NA值、负收入替换为NA值
  2. 使Chrome接受自签名的本地主机证书
  3. Docker(基础理解)
  4. 《深度探索C++对象模型》--7 站在对象模型的尖端
  5. python多列排序_Python prettytable按多列排序
  6. 信息收集之子域名查询--子域名扫描器: 子域名挖掘机 Subdomainsbrute---基本使用
  7. php网页的注册界面设计,HTML开发博客之注册页面设计(一)
  8. MSP430F5529 DriverLib 库函数学习笔记(十)SPI驱动墨水屏
  9. hdu 2089 不要62【数位dp】
  10. PTES_Technical_Guidelines(渗透测试执行标准)
  11. element手机验证格式_vue+element表单验证(身份证(校验),手机号码,导游证号码)...
  12. 一月集 一个会写诗的程序员2019
  13. 小程序跳转页面弹出公众号引导用户关注
  14. java hypot_Java StrictMath hypot()用法及代码示例
  15. Qt开发学生信息管理系统
  16. java程序调用时的调用规则,Java程序调用ILog规则出错
  17. 撷英阁-东瀛扶桑之零起点生存日语学习笔记
  18. 2020京东全球科技探索者大会来啦!三大体系CEO约你来开会!
  19. 生成一维码条码码,扫码查询相关条码信息
  20. linux安装vim plug,VIM 插件管理工具 vim-plug 简明教程

热门文章

  1. 主流mes厂商_MES市场的前景
  2. CIKM 2021 | Deep Retrieval:字节跳动深度召回模型论文精读
  3. 清华大学高阳:Mastering Atari Games with Limited Data
  4. CVPR 2019 | 旷视研究院提出TACNet,刷新时空动作检测技术新高度
  5. 直播 | 平安人寿资深算法工程师谢舒翼:智能问答系统探索与实践
  6. 深度学习在CTR预估中的应用 | CTR深度模型大盘点
  7. HDU1166 敌兵布阵 单点更新 区间查询
  8. 深度学习---英文名称简写大全
  9. es查询大文本效率_es中terms查询速度能否优化
  10. windbg 查看结构体_用WinDbg进行调试