概念

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. 有趣的后渗透工具 Koadic

    koadic是DEFCON黑客大会上分享出来的的一个后渗透工具,虽然和msf有些相似,但是Koadic主要是通过使用Windows ScriptHost(也称为JScript / VBScript)进 ...

  2. luogu P4762 [CERC2014]Virus synthesis (回文自动机)

    大意: 初始有一个空串, 操作(1)在开头或末尾添加一个字符. 操作(2)在开头或末尾添加该串的逆串. 求得到串$S$所需最少操作数. 显然最后一定是由某个偶回文通过添加字符得到的, 那么只需要求出所 ...

  3. 8-MySQL DBA笔记-测试基础

    第三部分 测试篇 测试需要掌握的知识面很广泛,本篇的关注点是数据库的性能测试和压力测试,对于其他领域的测试,由于涉猎不多,笔者就不做叙述了.DBA的工作职责之一就是评估软硬件,这往往是一项很耗时的工作 ...

  4. 关于Visual Studio 2019安装时共享组件、工具和 SDK安装位置不能更改的问题

    解决办法: 更改注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\Setup下的SharedInstallationPath项为所要的路径

  5. ItemsControl使用1

    <ItemsControl ItemsSource="{Binding DataItemsSource}"> //绑定一个List <ItemsControl.I ...

  6. Java Web-Cookie和Session

    Java Web-Cookie和Session 会话 会话的概念 一次会话是指浏览器从浏览器第一次给服务器发送请求建立到其中一方断开结束会话的一个过程.它包含多次请求和响应. 会话是用来在一次会话的范 ...

  7. [转载]clip gradient抑制梯度爆炸

    [转载]clip gradient抑制梯度爆炸 来源:https://blog.csdn.net/u010814042/article/details/76154391 1.梯度爆炸的影响 在一个只有 ...

  8. arcgis js 之 渔网工具(调用地图服务)

    arcgis js 之 渔网工具(调用地图服务) 原理: 简历不同级别的网渔网图层,设置显示比例尺.然后发布服务,使用MapImageLayer接收. 过程: 1.在arcmap中用创建渔网工具将不同 ...

  9. vuex数据传递的流程

    当组件修改数据的时候必须通过store.dispacth来调用actions中的方法. 当actions中的方法被触发的时候通过调用commit的方法来触发mutations里面的方法 mutatio ...

  10. django 权限控制精简版

    视图代码: 视图代码 def index(request): return render(request,'index.html') def login(request): if request.me ...