概念

synchronized 是 Java 中的关键字,是利用锁的机制来实现同步的。

锁机制有如下两种特性:

  • 互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。

  • 可见性:必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。

对象锁

synchronized修饰非静态方法时是对象锁,等同于synchronized(this),在同一个对象中是线程安全的。

package com.dwz.concurrency.chapter7;
/**
* 两个方法锁定的都是this即同一个对象thisLock,
* 同时调用的结果是一个执行完再执行下一个
*/
public class SynchronizedThis {
public static void main(String[] args) {
ThisLock thisLock = new ThisLock();
new Thread("T1") {
@Override
public void run() {
thisLock.m1();
}
}.start(); new Thread("T2") {
@Override
public void run() {
thisLock.m2();
}
}.start();
}
} class ThisLock {
  public synchronized void m1() {
try {
System.out.println(Thread.currentThread());
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public synchronized void m2() {
try {
System.out.println(Thread.currentThread());
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

执行结果:m1和m2先后执行

package com.dwz.concurrency.chapter7;
/**
* 锁定的是两个不同的对象,没有起到锁的作用,还是多线程执行
*/
public class SynchronizedThis2 {
public static void main(String[] args) {
ThisLock2 thisLock = new ThisLock2();
new Thread("T1") {
@Override
public void run() {
thisLock.m1();
}
}.start(); new Thread("T2") {
@Override
public void run() {
thisLock.m2();
}
}.start();
}
} class ThisLock2 {
private final Object LOCK = new Object(); public void m2() {
synchronized (LOCK) {
try {
System.out.println(Thread.currentThread());
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public void m1() {
synchronized (this) {
try {
System.out.println(Thread.currentThread());
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

执行结果:m1和m2同时执行

类锁

synchronized修饰静态方法时是类锁,等同于synchronized(类.class),是线程安全的。

package com.dwz.concurrency.chapter7;

public class SynchronizedStatic {
public synchronized static void m1() {
System.out.println("m1" + Thread.currentThread());
try {
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public synchronized static void m2() {
System.out.println("m2" + Thread.currentThread());
try {
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public synchronized static void m3() {
System.out.println("m3" + Thread.currentThread());
try {
Thread.sleep(10_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

测试类

package com.dwz.concurrency.chapter7;

public class SynchronizedTest2 {
public static void main(String[] args) {
new Thread("T1") {
@Override
public void run() {
SynchronizedStatic.m1();
};
}.start(); new Thread("T2") {
@Override
public void run() {
SynchronizedStatic.m2();
};
}.start(); new Thread("T3") {
@Override
public void run() {
SynchronizedStatic.m3();
};
}.start();
}
}

执行结果:T1 T2 T3是先后执行的

总结

1、对于静态方法,由于此时对象还未生成,所以只能采用类锁;

2、只要采用类锁,就会拦截所有线程,只能让一个线程访问。

3、对于对象锁(this),如果是同一个实例,就会按顺序访问,但是如果是不同实例,就可以同时访问。

4、如果对象锁跟访问的对象没有关系,那么就会都同时访问。

synchronized的对象锁和类锁的更多相关文章

  1. Java锁Synchronized,对象锁和类锁举例

    Java的锁分为对象锁和类锁. 1. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内针对该对象的操作只能有一个线程得到执行.另一个线程必须 ...

  2. Java锁Synchronized对象锁和类锁区别

    java的内置锁:每个java对象都可以用做一个实现同步的锁,这些锁成为内置锁.线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁.获得内置锁的唯一途径就是进入这个锁的保 ...

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

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

  4. Synchronized方法锁、对象锁、类锁区别

    synchronized,这个东西我们一般称之为”同步锁“,他在修饰代码块的时候需要传入一个引用对象作为“锁”的对象. 在修饰方法的时候,默认是当前对象作为锁的对象 在修饰类时,默认是当前类的Clas ...

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

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

  6. Java 中对象锁和类锁的区别? 关键字 Synchronized的用法?

    一  对象锁和类锁的关系 /* * 对象锁和[类锁] 全局锁的关系? 对象锁是用于对象实例方法,或者一个对象实例上的 this 类锁是用于类的静态方法或者一个类的class对象上的. Ag.class ...

  7. java的对象锁和类锁

    在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看这个关键字的用法. 因为synchronized关键字涉及到锁的概念,所以先来了解一些相关的锁知识. j ...

  8. java的synchronized有没有同步的类锁?

    转自:http://langgufu.iteye.com/blog/2152608 http://www.cnblogs.com/beiyetengqing/p/6213437.html 没有... ...

  9. java 对象锁和类锁的区别(转)

    java 对象锁和类锁的区别   转自; ) ); ; ) ); 上述的代码,第一个方法时用了同步代码块的方式进行同步,传入的对象实例是this,表明是当前对象,当然,如果需要同步其他对象实例,也不可 ...

随机推荐

  1. 今日js心得

    <input type="hidden" id="history_chart_json" data-json="#{smartDeviceMon ...

  2. eclipse svn 插件离线安装后connector获取不到的问题解决

    最近换了一家公司,写代码的电脑不给外网,所以各种麻烦的问题就来了,这里就说一下eclipse 安装SVN插件的一个小问题,虽说是小问题,但也折腾了我好几个小时,当然也可以不用这个插件,直接安装SVN客 ...

  3. mysql中binglog底层原理分析

    binglog 是一个二进制的日志文件,会记录mysql的数据更新或潜在个跟新 (delete from table where id =xxx) 主从复制就是依靠binglog master -sl ...

  4. 4.AOP原理模拟

    AOP   Aspect-Oriented-Programming    面向切面编程 a)是对面向对象的思维方式的有力补充 好处:可以动态的添加和删除在切面上的逻辑而不影响原来的执行代码 a)Fil ...

  5. 第二章、drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 (详细版)

    目录 drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 Postman接口工具 drf框架 注册rest_framework drf框架风格 drf请求生命周期 请求模块 ...

  6. 【异常】 Ensure that config phoenix.schema.isNamespaceMappingEnabled is consistent on client and server.

    1 详细异常 ror: ERROR 726 (43M10): Inconsistent namespace mapping properties. Ensure that config phoenix ...

  7. Flask debug 模式 PIN 码生成机制安全性研究笔记

    Flask debug 模式 PIN 码生成机制安全性研究笔记 0x00 前言 前几天我整理了一个笔记:Flask开启debug模式等于给黑客留了后门,就Flask在生产网络中开启debug模式可能产 ...

  8. 判断一个python字符串中是否包含中文字符

    #在python中一个汉字算一个字符,一个英文字母算一个字符 #用 ord() 函数判断单个字符的unicode编码是否大于255即可. def is_contain_chinese(check_st ...

  9. 03_Hive的交互方式

    之前使用的Shell方式只是Hive交互方式中的一种,还有一种就是将Hive启动为服务运行在一个节点上,那么剩下的节点 就可以使用客户端来连接它,从而也可以使用Hive的数据分析服务 1.Hive的交 ...

  10. ArcGIS水文分析实战教程(15)库容和淹没区计算

    库容和淹没区计算 的基本流程 要计算库容就必须先计算出该集水区面积,并且通过不同的水位计算出淹没区,并利用淹没区去裁剪DEM数据,将水面与下垫面的体积计算出来,这就是水库的库容.由于有了前面的基础,这 ...