我们在java开发中常常用synchronized( 互斥锁)来进行同步,但是对于 synchronized关键字有那些用法,会产生什么样的效果却不一定清楚,下面将详细介绍synchronized在程序中的使用方式。

一、Java 同步关键字(synchronized)

Java 中的同步块用synchronized 标记。同步块在Java 中是同步在某个对象上。所有同步在一个对象上的同步块在同时只能被一个线程进入并执行操作。所有其他等待进入该同步块的线程将被阻塞,直到执行该同步块中的线程退出。
有四种不同的同步块:
  • 实例方法
  • 静态方法
  • 实例方法中的同步块
  • 静态方法中的同步块
上述同步块都同步在不同对象上。实际需要那种同步块视具体情况而定。

(一)         实例方法同步

下面是一个同步的实例方法:
public synchronized void add(int value){
this.count+= value;
}
注意在方法声明中同步(synchronized  )关键字。这告诉Java 该方法是同步的。
Java 实例方法同步是同步在拥有该方法的对象上。这样,每个实例其方法同步都同步在不同的对象上,即该方法所属的实例。只有一个线程能够在实例方法同步块中运行。如果有多个实例存在,那么一个线程一次可以在一个实例同步块中执行操作。一个实例一个线程。

(二)         静态方法同步

静态方法同步和实例方法同步方法一样,也使用synchronized  关键字。Java 静态方法同步如下示例:
public static synchronized void add(intvalue){
count += value;
}
同样,这里synchronized  关键字告诉Java 这个方法是同步的。
静态方法的同步是指同步在该方法所在的类对象上。因为在Java 虚拟机中一个类只能对应一个类对象,所以同时只允许一个线程执行同一个类中的静态同步方法。
对于不同类中的静态同步方法,一个线程可以执行每个类中的静态同步方法而无需等待。不管类中的那个静态同步方法被调用,一个类只能由一个线程同时执行。

(三)         实例方法中的同步块

有时你不需要同步整个方法,而是同步方法中的一部分。Java 可以对方法的一部分进行同步。
在非同步的Java 方法中的同步块的例子如下所示:
public void add(int value){
synchronized(this){
this.count += value;
}
}
示例使用Java 同步块构造器来标记一块代码是同步的。该代码在执行时和同步方法一样。
注意Java 同步块构造器用括号将对象括起来。在上例中,使用了“this” ,即为调用add 方法的实例本身。在同步构造器中用括号括起来的对象叫做监视器对象。上述代码使用监视器对象同步,同步实例方法使用调用方法本身的实例作为监视器对象。
一次只有一个线程能够在同步于同一个监视器对象的Java 方法内执行。
下面两个例子都同步他们所调用的实例对象上,因此他们在同步的执行效果上是等效的。
public class MyClass {
public synchronized void log1(String msg1,String msg2){
log.writeln(msg1);
log.writeln(msg2);
}
public void log2(String msg1, String msg2){
synchronized(this){
log.writeln(msg1);
log.writeln(msg2);
}
}
}
在上例中,每次只有一个线程能够在两个同步块中任意一个方法内执行。
如果第二个同步块不是同步在this 实例对象上,那么两个方法可以被线程同时执行。

(四)         静态方法中的同步块

和上面类似,下面是两个静态方法同步的例子。这些方法同步在该方法所属的类对象上。
public class MyClass {
public static synchronized void log1(Stringmsg1, String msg2){
log.writeln(msg1);
log.writeln(msg2);
}
public static void log2(String msg1, Stringmsg2){
synchronized(MyClass.class){
log.writeln(msg1);
log.writeln(msg2);
}
}
}
这两个方法不允许同时被线程访问。
如果第二个同步块不是同步在MyClass.class 这个对象上。那么这两个方法可以同时被线程访问。

(五)         Java同步实例

在下面例子中,启动了两个线程,都调用Counter 类同一个实例的add 方法。因为同步在该方法所属的实例上,所以同时只能有一个线程访问该方法。
publicclass Counter{
long count = 0;
public synchronized void add(long value){
this.count += value;
}
}
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);
}
}
}
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 方法是同步在实例上,是因为add 方法是实例方法并且被标记上synchronized 关键字。因此每次只允许一个线程调用该方法。另外一个线程必须要等到第一个线程退出add() 方法时,才能继续执行方法。
如果两个线程引用了两个不同的Counter 实例,那么他们可以同时调用add() 方法。这些方法调用了不同的对象,因此这些方法也就同步在不同的对象上。这些方法调用将不会被阻塞。如下面这个例子所示:
public static voidmain(String[] args){
Counter counterA = new Counter();
Counter counterB = new Counter();
Thread  threadA = newCounterThread(counterA);
Thread  threadB = newCounterThread(counterB);
threadA.start();
threadB.start();
}
}
注意这两个线程,threadA 和threadB ,不再引用同一个counter 实例。CounterA 和counterB 的add 方法同步在他们所属的对象上。调用counterA 的add 方法将不会阻塞调用counterB 的add 方法。

一、使用总结 
1、如果在应用中为了确保某个业务方法在程序启动的时候执行一次或者执行次数很少,那么建议在方法(实例方法,静态方法)上添加 synchronized关键字,可以保证同一时刻只有一个线程可以调用此方法。  
2、在高并发中不建议在方法上添加 synchronized,因为这样限制了线程并发的数量,相当于变成了单线程的调用,在这种情况下,建议在方法块中添加 synchronized 关键字,只给需要同步的对象加锁,减小锁的范围。 
3、在高并发中读多,写少建议使用ReadWriteLock,关于读写锁的使用,请参看 java中读写锁的使用

转载于:https://www.cnblogs.com/merlini/p/3975143.html

【线程同步】 Java 同步块(synchronized)详细说明相关推荐

  1. java 代码块同步,Java 同步代码块

    Java 同步代码块 1 什么是Java同步代码块 同步代码块可用于对方法的任何特定资源执行同步. 假设您的方法中有50行代码,但是您只想同步5行,则可以使用synchronized代码块. 如果将方 ...

  2. java类同步,Java同步工具類(一)

    同步工具類可以是任意一個對象,只要它可以根據自身的狀態來協調線程的控制流.阻塞隊列可以作為同步工具類,其他類型的同步工具類還包括信號量(Semaphore).柵欄(Barrier)以及閉鎖.在平台類庫 ...

  3. Java线程同步学习,线程不安全案例讲解,同步方法和同步块 synchronized

    本文主要是自己学习多线程时,所做的笔记,参考的是b站狂神说Java多线程视频讲解. 目录如下: 文章目录 线程同步 一.三大线程不安全案例 1.买票案例 2.不安全取钱 3.线程不安全 二.同步方法及 ...

  4. java同步锁售票_Java基础学习笔记: 多线程,线程池,同步锁(Lock,synchronized )(Thread类,ExecutorService ,Future类)(卖火车票案例)...

    学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线程:线程是 ...

  5. java同步关键词解释、synchronized、线程锁(Lock)

    1.java同步关键词解释 21.1 synchronized synchronized是用来实现线程同步的!!! 加同步格式: synchronized( 需要一个任意的对象(锁) ){ 代码块中放 ...

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

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

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

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

  8. java runnable线程锁_多线程 java 同步 、锁 、 synchronized 、 Thread 、 Runnable

    线程 1 线程概述 1.1 什么是线程 v  线程是程序执行的一条路径, 一个进程中可以包含多条线程 v  一个应用程序可以理解成就是一个进程 v  多线程并发执行可以提高程序的效率, 可以同时完成多 ...

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

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

最新文章

  1. 用C#创建Windows服务(Windows Services)
  2. SAXReader解析xml繁体字乱码问题
  3. OpenGL:ImGUI在GLFW库和GLAD/GLEW库的环境下使用
  4. [POJ1155]TELE
  5. SpringBoot 配置 generator代码生成+knife4j接口文档(2种模板设置、逻辑删除、字段填充 含代码粘贴可用)保姆级教程(注意事项+建表SQL+代码生成类封装+测试类)
  6. Nagios远程监控软件的安装与配置详解
  7. php用ajaxs上传图片_jquery+ajax+php 图片上传
  8. VMware下的ubuntu12.04不识别usb设备问题的解决方法
  9. 请大家推荐几个快速的.net+sql server2005的虚拟主机
  10. vfp中写入文本文件_VFP文件操作函数用法.doc
  11. vue项目前端页面模板,基于vue的前端模板
  12. 斐讯N1刷无线打印服务器,斐讯N1刷armbian制作cups打印服务器支持airprint不使用foo2zjs|hp1020...
  13. 逐点比较法直线插补MATLAB
  14. 在egret中自制帧动画
  15. (华为社招岗位,部门---公共开发部,数字能源,计算,Carbu, 上海海思,GTS,海思,2012):上海!上海上海!
  16. office的入门到进阶
  17. Vue.js 响应式原理
  18. winmail 数据库设置_Windows - 2003下搭建邮件服务器教程和使用 - Winmail - Server - 轻松架设邮件服务器 - 图文...
  19. 威尔特拉斯定理_数学大师启示录维尔斯特拉斯.pdf
  20. 【Benewake(北醒) 】长距 TF350 350m介绍以及资料整理

热门文章

  1. 百度定位到非洲的问题
  2. 台式计算机在打开程序时 风扇就响,如果台式机正在运行时风扇响了怎么办?...
  3. android数据库侵入,Android中实现侵入式状态栏的两种方式
  4. 一名合格的前端开发工程师应该掌握的8个技能
  5. 帮我用python写一个智能AI的狼吃羊
  6. 泰山OFFICE技术讲座:由WORD奇怪的字体高度,谈字体的布局高度
  7. 分布式缓存——Redis高级彻底搞懂(Redis原理+主从+集群)
  8. 每月一书(202105):《原则》
  9. CoOS使用教程——任务的状态
  10. 【包会教程】“批打”神器教程