synchronized对于加锁代码块、方法以及全局(static)锁的详细对比

本文详细分析了Java中synchronized锁在对象锁、类锁以及代码块锁场景下的行为。通过多个实例测试,展示了同一对象访问加锁方法和代码块时的相互约束,不同对象访问同一加锁方法或代码块时的并发情况,以及静态锁和实例锁的差异。此外,还探讨了锁代码块中使用synchronized(this)和synchronized(Class)的区别,指出它们对并发控制的影响。文章最后提出了对synchronized更深入研究的问题,如锁的重入性和锁对象的选择等。
摘要由CSDN通过智能技术生成

在网上看了许多关于synchronized的介绍及用法区别,大多大同小异,点到为止,个人推荐一篇博友写的,

网址如下:http://blog.csdn.net/cs408/article/details/48930803

这篇博客是介绍对象锁和类锁的区别,通俗易懂,而我的这篇博客是基于此基础上引申出,用实际的代码分析对象和类在方法、代码段加锁及静态时的对比。

开始先普及一下java里synchronized锁的一些概念:有分为对象锁类锁两种。对象锁(又称作实例锁),是指锁在某一个实例对象上的;类锁(又称作全局锁),是锁针对类上的,无论实例多少该类对象,都是共享该锁。

一、首先是这样一个列子,设计一个多线程的类TestSynchronized,有如下方法:

 
class TestSynchronized{
	public synchronized void test_one(){ //加锁的实例方法
		System.out.println(Thread.currentThread().getName()+" begin time: "+System.currentTimeMillis());
                //记录某线程进入此方法时的时间
		try{
			Thread.sleep(1000); //某线程睡眠1秒
		}catch (Exception e) {}
		System.out.println(Thread.currentThread().getName()+"   end time: "+System.currentTimeMillis());
                //记录某线程结束此方法时的时间
	}
	public synchronized void test_one_cope(){ //加锁的实例方法
		//内容同上方法内....
	}
        public static synchronized void test_two(){ //加锁的类方法
		//内容同上方法内....
	}
        public static synchronized void test_two_cope(){ //加锁的类方法
		//内容同上方法内....
	}
}

在主函数测试中,给每个方法对应一个线程:

Thread thread = new Thread( //一个线程测一个方法
	new Runnable() {
		public void run() {
			//test(); //方法名
		}
	}
);
thread.setName("..."); //给线程添加名字,便于结果读取

新建两个TestSynchronized对象A和B,有如下对比:

测试序号 对象 静态 加锁方法 对象 静态 加锁方法
1 A × test_one() A × test_one_cope()
2 A × test_one() B × test_one()
3 A × test_one() A test_two()
4 A test_two() B test_two()
5
在Java中,可以使用关键字 `synchronized` 来对全局变量进行加锁。关键字 `synchronized` 可以应用于方法代码块,以确保在同一时间只有一个线程可以访问被加锁的代码。 如果你想对全局变量进行加锁,可以在访问该全局变量代码块方法前使用 `synchronized` 关键字。这将确保在同一时间只有一个线程可以访问该代码块方法。 下面是一个示例,展示了如何在Java中对全局变量进行加锁: ```java public class GlobalVariableExample { private static int globalVariable = 0; public static void main(String[] args) { // 创建多个线程并启动 for (int i = 0; i < 5; i++) { Thread thread = new Thread(new Runnable() { @Override public void run() { incrementGlobalVariable(); } }); thread.start(); } } public static synchronized void incrementGlobalVariable() { // 加锁了的代码块 globalVariable++; System.out.println("Global variable value: " + globalVariable); } } ``` 在上面的示例中,`incrementGlobalVariable()` 方法被声明为 `synchronized`,这意味着在同一时间只有一个线程可以执行该方法。因此,当多个线程尝试同时访问 `incrementGlobalVariable()` 方法时,只有一个线程能够成功执行,确保全局变量的操作是安全的。 请注意,如果多个线程都需要同时访问全局变量的不同部分,你可能需要更细粒度的机制,例如使用 `Lock` 接口和 `ReentrantLock` 类来实现更复杂的加锁逻辑。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值