前文:java中多线程的锁,分为两种,悲观锁和乐观锁。使用synchronized作为锁的形式,就是悲观锁,又称为同步锁。
一、synchronized原理
- 在java中,每一个对象有且仅有一个同步锁。同步锁是依赖于对象而存在。
- 当我们调用某对象的synchronized方法时,就获取了该对象的同步锁。
- 不同线程对同步锁的访问是互斥的。
通俗一点:N个线程同时访问对象A的方法时,如果线程X获得了对象A的同步锁,线程X可以执行A对象的synchronized方法,或者A对象的synchronized代码块。
其他线程不能访问A对象的synchronized方法,或者A对象的synchronized代码块,只可以访问对象A的非同步方法或者代码。其他线程只能等待线程X执行完方法之后,线程X释放了对象A的同步锁,其他线程获得对象A的同步锁,才可以执行A对象的synchronized方法,或者A对象的synchronized代码块。
推导出三个基本规则:
- 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的该“synchronized方法”或者“synchronized代码块”的访问将被阻塞。
- 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程仍然可以访问“该对象”的非同步代码块。
- 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的其他的“synchronized方法”或者“synchronized代码块”的访问将被阻塞。
“synchronized方法”是用synchronized修饰方法,而 “synchronized代码块”则是用synchronized修饰代码块。
synchronized方法示例
public synchronized void foo1() { System.out.println("synchronized methoed"); }
synchronized代码块
public void foo2() { synchronized (this) { System.out.println("synchronized methoed"); } }
synchronized代码块中的this是指当前对象。也可以将this替换成其他对象,例如将this替换成obj,则foo2()在执行synchronized(obj)时就获取的是obj的同步锁。
三、 实例锁 和 全局锁
实例锁 -- 锁在某一个实例对象上。如果该类是单例,那么该锁也具有全局锁的概念。
实例锁对应的就是synchronized关键字。
全局锁 -- 该锁针对的是类,无论实例多少个对象,那么线程都共享该锁。
全局锁对应的就是static synchronized(或者是锁在该类的class或者classloader对象上)。
关于“实例锁”和“全局锁”有一个很形象的例子:
pulbic class Something { public synchronized void isSyncA(){} public synchronized void isSyncB(){} public static synchronized void cSyncA(){} public static synchronized void cSyncB(){} }
假设,Something有两个实例x和y。下面4组表达式获取的锁的情况。
(1)、x.isSyncA()与x.isSyncB()
不能被同时访问。因为isSyncA()和isSyncB()都是访问同一个对象(对象x)的同步锁
(2)、x.isSyncA()与y.isSyncA()
可以同时被访问。因为访问的不是同一个对象的同步锁,x.isSyncA()访问的是x的同步锁,而y.isSyncA()访问的是y的同步锁。
(3)、 x.cSyncA()与y.cSyncB()
不能被同时访问。因为cSyncA()和cSyncB()都是static类型,x.cSyncA()相当于Something.isSyncA(),y.cSyncB()相当于Something.isSyncB(),因此它们共用一个同步锁,不能被同时访问。
(4)、x.isSyncA()与Something.cSyncA()
可以被同时访问。因为isSyncA()是实例方法,x.isSyncA()使用的是对象x的锁;而cSyncA()是静态方法,Something.cSyncA()可以理解对使用的是“类的锁”。因此,它们是可以被同时访问的。
四、小结
线程本身是没有锁的,
锁在对象身上,每个对象只有一把同步锁,
如果线程希望执行对象的同步方法,或者同步代码块,线程就必须获得对象的同步锁,才能执行对象的同步方法,才能安全有序的共享对象资源。
相关推荐
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
`@synchronized`关键字是Apple提供的一种简便的同步机制,它可以帮助开发者确保在多线程环境下对共享资源进行原子性操作,防止数据竞争问题。本文将深入探讨`@synchronized`的工作原理、特点以及使用时需要注意的...
- `synchronized`用于实现线程同步,防止数据的不一致性。它可以修饰方法或代码块,当一个线程进入同步块/方法后,其他线程必须等待其释放锁才能进入。 - 同步锁机制通过监视器锁(Monitor)实现,每个对象都有一...
多线程注意:wait()方法的调用要有判定条件常用 while () obj.wait(timeout, nanos); ... // Perform action appropriate to condition } synchronized会影响共享数据,但对其他语句的执行不会有规律了!
Java 多线程与并发中的 synchronized 关键字是实现同步块的互斥访问和线程的阻塞及唤醒等工作的重要工具。下面将对 synchronized 关键字进行详细分析。 synchronized 关键字的使用场景 synchronized 关键字可以...
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
在Java语言中,synchronized关键字用于对方法或者代码块进行同步,但是仅仅使用synchronized关键字还不能满足对多线程进行同步的所有需要。因此,需要使用其他同步机制来满足不同的同步需求。 Java 多线程同步中的...
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
Java中的多线程和线程同步是编程中关键的概念,特别是在处理并发操作和优化性能时。下面我们将深入探讨这些主题。 首先,线程是程序执行的独立路径,它允许一个程序同时执行多个任务。在Java中,我们有两种方式创建...
在Java编程中,多线程同步是一个至关重要的概念,它确保了多个线程在访问共享资源时能够有序进行,防止数据不一致性和竞态条件。`synchronized`关键字是Java中实现线程同步的主要手段之一。这篇文档主要讨论了如何...
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
标题中的"java 多线程synchronized互斥锁demo"指的是一个示例,展示了如何在多线程环境下使用`synchronized`关键字创建互斥锁,确保同一时间只有一个线程可以访问特定的代码块或方法。 描述中的"一个多线程访问的同...
本资料“Java多线程基础-01、数组概述”将带你入门Java的多线程世界,并结合数组这一基本数据结构进行讲解。 首先,我们需要理解什么是线程。线程是操作系统分配CPU时间的基本单位,一个进程可以有多个线程,它们...
本示例“简单实现多线程同步示例(模拟购票系统)”旨在通过一个具体的实例,帮助开发者理解如何在Java中创建并管理多线程以及如何实现线程同步,确保数据的一致性和正确性。 首先,我们要明确多线程的基本概念。在...