synchronized 分为对象锁,和实例锁。
先看实例锁:
public class Test {
private void lock1() {
synchronized (this) {
try {
System.out.println("lock1方法开始执行");
Thread.sleep(5000);
} catch (Exception e) {
}
System.out.println("lock1方法执行完毕");
}
}
private void lock2() {
synchronized (this) {
try {
System.out.println("lock2方法开始执行");
Thread.sleep(1000);
} catch (Exception e) {
}
System.out.println("lock2方法执行完毕");
}
}
public static void main(String[] args) {
final Test test = new Test();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
test.lock1();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
test.lock2();
}
});
t1.start();
t2.start();
}
}
运行结果:
lock1方法开始执行
lock1方法执行完毕
lock2方法开始执行
lock2方法执行完毕
线程1和线程2会排队执行,因为他们都是要求同步的方法,而且他们会依赖于同一个实例,test。而synchronized (this)会锁定这个实例。需要注意的是:t1和方t2谁先抢到锁是随机的。
我们把main方法改一改
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
new Test().lock1();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
new Test().lock2();
}
});
t1.start();
t2.start();
}
运行结果:
lock2方法开始执行
lock1方法开始执行
lock2方法执行完毕
lock1方法执行完毕
可以看到没有达到同步的效果,这是因为在线程t1,t2中,每次都是new Test(),运行的是不同的实例,大家各行其道!
要是这种情况也需要同步怎么办,这就要用到对象锁啦。我们把lock1和lock2方法的锁类型改一下
private void lock1() {
synchronized (Test.class) {
try {
System.out.println("lock1方法开始执行,Test对象类被锁定----");
Thread.sleep(5000);
} catch (Exception e) {
}
System.out.println("lock1方法执行完毕,Test对象锁被释放----");
}
}
private void lock2() {
synchronized (Test.class) {
try {
System.out.println("lock2方法开始执行,Test对象类被锁定....");
Thread.sleep(1000);
} catch (Exception e) {
}
System.out.println("lock2方法执行完毕,Test对象锁被释放....");
}
}
执行结果:
lock1方法开始执行,Test对象类被锁定----
lock1方法执行完毕,Test对象锁被释放----
lock2方法开始执行,Test对象类被锁定....
lock2方法执行完毕,Test对象锁被释放....
可以看到, 在线程t1,t2中,我们都是new 不同的 test实例来执行,但是lock1方法和lock2方法仍然会排队执行。一旦一个方法比如lock1先抢到了锁,lock2会等待lock1完全执行完毕,才开始执行。就是说对象锁,锁定了所有对象的所有实例!
题外话,看看对象锁父类子类的关系。把lock1方法稍微改一下,锁定Test对象的父类Object对象,
private void lock1() {
synchronized (Object.class) {
try {
System.out.println("lock1方法开始执行,Object对象类被锁定----");
Thread.sleep(5000);
} catch (Exception e) {
}
System.out.println("lock1方法执行完毕,Object对象锁被释放----");
}
}
运行结果:
lock1方法开始执行,Object对象类被锁定----
lock2方法开始执行,Test对象类被锁定....
lock2方法执行完毕,Test对象锁被释放....
lock1方法执行完毕,Object对象锁被释放----
lock1和lock2方法会插队执行。结果表明对于锁来说,父类是父类,子类是子类,没有一点关系。
此外 synchronized 关键词还有一种是加在方法上,但是一般很少使用,因为一般来说,不是方法里的所有代码都会同步!对于加在普通方法上的同步,完全等价于synchronized(this), 对于加在静态方法上的同步,完全等价于对象锁synchronized(this.getClass()),此处不提。
现实生活中,经常有的一种需求是,处于对象锁与实例锁之间,假如说,我有一个Product,id是100,某个时刻只允许一个人修改这条数据,类似于数据库的行锁,java也可以实现这种需求。
首先绝对不能用对象锁锁Product.class,否则同一时刻,只能操作一个商品。这是绝对不能接受的!而且从实际出发id=99和id=100的实例我们也完全不需要同步!
但是可能同一个时刻在很多地方都有id=100的Product实例,典型的是在web环境中,多个请求(即多个线程)同时购买一个商品,要修改这个商品库存!我们想把Product的所有id=100的实例的库存同步!
我们可以用 map的 key,value特性来做这个事!详情参阅http://supben.iteye.com/blog/1416404
警告:因为这个方法是在内存级别的锁定,不同于数据库的硬盘级,所以只有在单机情况下有那么点意义!!。事实上,有这种并发级别的商城,肯定都是分布式的了。
分享到:
相关推荐
java多线程中synchronized关键字的用法 解压密码 www.jiangyea.com
Java 线程同步机制中 synchronized 关键字的理解 Java 的线程同步机制是为了解决多个线程共享同一片存储空间所带来的访问冲突问题。其中,synchronized 关键字是 Java 语言中解决这种冲突的重要机制。 ...
Java中的`synchronized`关键字是多线程编程中的一个重要概念,用于控制并发访问共享资源时的同步机制。在Java中,当多个线程试图同时访问和修改同一块代码或数据时,可能会导致数据不一致的问题。为了解决这个问题,...
Java提供了多种机制来处理并发问题,其中synchronized关键字是最基本也是最常用的同步手段之一。本文将深入探讨synchronized关键字的工作原理、使用方式以及在实际编程中的应用。 synchronized关键字是Java中实现...
Java 中的 synchronized 关键字与线程平安问题 在 Java 中,synchronized 关键字是一个非常重要的概念,它用于解决线程同步问题。但是,很多开发者对 synchronized 关键字的理解并不够深入,本文将通过实例解析 ...
### synchronized关键字的深入解析 #### 一、synchronized关键字的重要性 `synchronized`关键字在Java语言中扮演着极其重要的角色,它是实现线程安全的核心手段之一。通过`synchronized`关键字,开发人员可以在多...
本文深入探讨了Java中用于解决并发编程中线程安全问题的synchronized关键字。文章首先讨论了多线程编程中临界资源的概念,包括对象、变量、文件等,以及同步机制的必要性。重点解析了synchronized的工作原理,包括其...
Java 并发编程 Synchronized 关键字实现原理 Synchronized 关键字是 Java 并发编程中最基本的同步机制,它可以保证线程安全,包括原子性、可见性和有序性。Synchronized 关键字可以修饰方法或代码块,使得在同一...
一、synchronized关键字的作用与原理 `synchronized`关键字主要有两个作用:同步方法和同步块。它通过锁机制来实现线程同步,防止多个线程同时执行同一段代码,可能导致的数据不一致问题。 1. 同步方法:当在方法...
### Lock接口与synchronized关键字详解 #### 一、概述 在Java并发编程中,Lock接口与synchronized关键字都是实现同步的重要工具。它们虽然都用于控制多线程对共享资源的访问,但在使用方式、功能特性及灵活性方面...
### Synchronized关键字在Java中的应用 #### 概述 `synchronized`是Java语言中的一个关键字,主要用于实现线程同步,防止多个线程同时访问共享资源而导致的数据不一致问题。通过`synchronized`关键字,开发者可以...
《深入理解Java中的synchronized关键字》 在Java编程语言中,`synchronized`关键字是用于实现线程同步的重要工具,它的本质在于确保多线程环境下的数据一致性与安全性。通过`synchronized`,我们可以控制对共享资源...
本文将探讨Synchronized关键字在解决并发控制中的作用及其使用方式。 首先,让我们回顾一下问题的背景:在给出的示例代码中,创建了10个线程,每个线程都对共享变量`count`进行10000000次的累加操作。理论上,最终...
### Java synchronized 关键字原理与自定义锁实现详解 #### 一、Java synchronized 关键字原理 `synchronized` 是 Java 中的关键字之一,用于实现线程间的同步控制,确保共享资源的安全访问。它主要应用于以下两种...
线程安全,使用synchronized关键字
5-4JVM内置锁synchronized关键字详解.mp4
synchronized关键字是Java中实现线程同步的基本工具,它通过锁定对象的monitor来控制对共享资源的并发访问。理解synchronized的工作原理和使用方式对于编写线程安全的Java程序至关重要。然而,由于其局限性,开发者...
"Java 多线程与并发(4-26)-关键字- synchronized详解" Java 多线程与并发中的 synchronized 关键字是实现同步块的互斥访问和线程的阻塞及唤醒等工作的重要工具。下面将对 synchronized 关键字进行详细分析。 ...
需要注意的是,synchronized关键字的使用需要遵守一定的原则,例如避免使用synchronized关键字在循环语句中,以免出现死锁等问题。此外,synchronized关键字也可以与其他线程同步工具结合使用,以实现更复杂的线程...