第五章java中的对象级锁定与类级锁定|
同步是将对共享资源的访问限制为仅一个线程的能力。当两个或多个线程需要访问共享资源时,必须有某种机制使得共享资源只能由一个线程使用。我们可以实现它的过程称为同步。
为什么需要同步?
让我们借助示例来理解这一点。 假设您想计算针对特定 URL 获得的请求数。如果同时收到两个请求,那么 count 可能会不一致。
不同步:
package org.arpit.java2blog;
public class RequestCounter {
private int count;
public int incrementCount()
{
count++;
return count;
}
}
例如: 线程 T1 看到 count 为 20 并递增到 21。同时线程 t2 也看到 count 为 20 并将其递增到 21。这表明 count 变得不一致。
同步:
您可以使用两种方式实现同步。
- 同步方法
- 同步块
同步方法
您可以使整个 incrementCount() 方法同步,因此没有两个线程可以并行访问它。
package org.arpit.java2blog;
public class RequestCounter {
private int count;
public synchronized int incrementCount()
{
count++;
return count;
}
}
例如: 线程 T1 看到计数为 20 并将其增加到 21。同时,线程 t2 现在将看到计数为 21 并将其增加到 22。
同步块
您可以在 incrementCount() 方法中使用 block 来同步临界区,这样就没有两个线程可以同时访问 block。
package org.arpit.java2blog;
public class RequestCounter {
private int count;
public int incrementCount() {
synchronized (this) {
count++;
return count;
}
}
}
例如: 线程 T1 看到计数为 20 并将其增加到 21。同时,线程 t2 现在将看到计数为 21 并将其增加到 22。
java中有两种类型的锁定。
-
对象级锁定
-
类级别锁定
对象级锁定:
对象级锁定意味着您希望同步非静态方法或块,以便该实例一次只能由一个线程访问。如果要保护非静态数据,则使用它。
您可以通过以下方式实现对象级锁定。
使方法同步:
public synchronized int incrementCount()
{
}
使用同步块并锁定:
public int incrementCount() {
synchronized (this) {
count++;
return count;
}
使用同步块并锁定其他对象:
private final Object lock=new Object();
public int incrementCount() {
synchronized (lock) {
count++;
return count;
}
类级别锁定:
类级锁定意味着您要同步静态方法或块,以便整个类只能由一个线程访问。如果您有 10 个类实例,则只有一个线程一次只能访问任何一个实例的一种方法或块。如果要保护静态数据,则使用它。
这可以通过以下方式实现:
使静态方法同步:
public static synchronized int incrementCount()
{
}
在 .class 上使用同步块和锁定:
public int incrementCount() {
synchronized (RequestCounter.class) {
count++;
return count;
}
使用同步块并锁定其他一些静态对象:
private final static Object lock=new Object();
public int incrementCount() {
synchronized (lock) {
count++;
return count;
}
两个线程可以同时执行静态和非静态方法吗?
是的,由于两个线程将获取不同对象的锁,因此它们可以同时执行而不会出现任何问题。
如果一个类的方法是同步的,而同一个类的另一个方法是不同步的?它们可以由两个线程同时执行吗?
是的,因为一个线程需要锁才能进入同步块,而第二个线程将执行不需要任何锁的非同步方法,所以它可以并发执行。
从另一个同步方法调用同步方法是否安全?
是的,从另一个同步方法调用同步方法是安全的,因为当您调用同步方法时,您将获得对该对象的锁定,而当您调用同一类的另一个同步方法时,执行是安全的,因为它已经锁定这个对象。 例如:
public synchronized void method1() {
method2();
// some code
}
public synchronized void method2() {
// some code
}
你实际上正在这样做。
public void method1() {
synchronized (this) {
method2();
// some code
}
}
public void method2() {
synchronized (this) {
// some code
}
}
这里如果任何线程从method1调用method2,它已经锁定了这个对象,因此执行是安全的。
相关文章:
- [其它]第六章JavaFutureTask示例|
- [其它]第六章JavaScheduledThreadPoolExecutor示例|
- [其它]第六章使用Callable和Future的JavaExecutorService示例|
- [其它]第六章JavanewCachedThreadPool示例|
- [其它]第六章JavanewFixedThreadPool示例|
- [其它]第六章:为什么我们需要Executor框架?|
- [其它]第五章在java中使用3个线程打印序列|
- [其它]第五章java中notify和notifyAll的区别|
- [其它]第五章我们可以在java中启动一个线程两次吗|
- [其它]第五章Java线程连接示例|
相关推荐:
- [其它]第三章java中的抽象类|
- [其它]第四章java中的TreeMap与示例|
- [其它]第四章java中的hashcode()和equals()方法|
- [其它]第六章JavaFutureTask示例|
- [其它]计算机组成原理PDF扫描格式电子版百度云网盘下载
- [其它]程序设计语言概念(第9版)[Robert W. Sebesta]pdf格式电子版百度云网盘下载[53.8M]
- [其它]程序员必读之软件架构[Simon Brown]pdf格式电子版百度云网盘下载[41.6M]
- [其它]程序员的思维修炼 开发认知潜能的九堂课[Andy Hunt]pdf格式电子版百度云网盘下载
- [其它]程序员的职业素养[Robert C. Martin]pdf格式电子版百度云网盘下载[21.6M]
- [其它]程序员教程(第3版)[张淑平]pdf格式电子版百度云网盘下载[136.5M]
- 计算机组成原理PDF扫描格式电子版百度云网盘下载
- 硅谷之谜[吴军]pdf格式电子版百度云网盘下载[59.5M]
- 自选基金助手,一款Chrome扩展程序
- 七周七语言 理解多种编程范型[Bruce A. Tate]pdf格式电子版百度云网盘下载[9M]
- 系统集成项目管理工程师考试考眼分析与样卷解析(2014版)[软考新大纲研究组]
- 程序员面试金典(第5版)[Gayle Laakmann McDowell]pdf格式电子版百度云网盘下载[81.5M]
- 创业维艰 如何完成比难更难的事[Ben Horowitz]pdf格式电子版百度云网盘下载[65.3
- 程序员的思维修炼 开发认知潜能的九堂课[Andy Hunt]pdf格式电子版百度云网盘下载
- 图灵的秘密 他的生平、思想及论文解读[Charles Petzold]pdf格式电子版百度云网盘下
- OCP OCA认证考试指南全册:Oracle Database 11g(1Z0-051、1Z0-052、1Z0-053)[John Watson]pdf格式