一. this 锁

同步函数其实用到的锁就是 this 锁,为什么他用到的是 this 锁呢?为了证实这个结论我 们本节将会有两个实验性的程序来作为支撑,说服自己和读者证明同步函数用到的就是 this 锁好了,请看下第一个程序

需求:

我们定义一个类,其中有两个方法,均加了同步锁,假设函数的同步不是 this 锁,我们 如果启动一个线程调用方法 A,另外一个线程调用用方法 B,A 方法和 B 方法里均是死循环, 按照同步函数不是 this 锁的逻辑,两个函数中的逻辑将会被同时执行,但是情况是否是这样, 我们需要通过代码进行实验

public class ClassA {
public synchronized void A()
{
System.out.println("AAAAAAAAAAAAAAAAA");
while (true)
{
} }
public synchronized void B()
{
System.out.println("BBBBBBBBBBBBBBBBB");
while (true)
{
}
}
}
public class MethodSynchronizedTest {

    public static void main(String[] args) {
final ClassA clazz = new ClassA();
// 启动一个线程
new Thread(new Runnable() {
public void run() {
clazz.A();// 调用A方法
}
}).start(); // 启动另一个线程
new Thread(new Runnable() {
public void run() {
clazz.B();// 调用B方法
}
}).start(); }
}

分别启动了两个线程,分别用来执行 ClassA 中的两个方法 A 和 B,两个方法都是加了锁 的,也就是说某个线程尽到方法 A 中其他线程就不能进入 A,但是另一个线程应该能进入 B, 但是我们等了半天方法 B 仍然没有输出,因此我们得出一个结论,他们的锁是同一个,至于 是哪一个锁呢?答案就是 this 锁;但是这个例子似乎还不过瘾,那么我们继续修正叫号的程 序,让读者有一个更加直观的理解;

需求: 我们增加一个方法,也用来进行叫号,在 run 方法中也进行叫号,第一个线程调用 run 方法中的逻辑,第二个方法调用函数中的逻辑;

public class TicketWindow3 implements Runnable {

    private int max_value = 0;

    private Object lock = new Object();

    private boolean flag = true;

    @Override
public void run() {
if (flag) {
while (true) {
//同步函数其实用到的锁就是 this 锁, this锁针对的是对象
//静态锁,锁是类的字节码信息,因此如果一个类的函数为静态方法,那么我们需要通过该类的 class 信息进行加锁;
synchronized (lock) {
if (max_value > 500) {
break;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + ":lock..." + max_value++);
}
}
} else {
while (true)
if (ticket())
break;
} } private synchronized boolean ticket() {
if (max_value > 500) {
return true;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + ": method.." + max_value++);
return false;
} public void change() throws InterruptedException {
Thread.sleep(30);// 读者可以自行思考为什么要sleep
this.flag = false;
} }
public class Bank3 {

    public static void main(String[] args) throws InterruptedException {
TicketWindow3 tw3 = new TicketWindow3();
Thread t1 = new Thread(tw3);
Thread t2 = new Thread(tw3);
t1.start();
tw3.change();
t2.start();
}
}

文字说明: 可能到输出性信息,其中会有 501 这样的信息输出,为什么会这样呢?因为上述的代码 两处业务逻辑同步锁是两把锁,如果您将 lock 换成 this,这个现象就不会出现,读者可 以自己进行测试;

2 static 锁

如果我们的方法 ticket 是一个静态方法,再次测试一下您会发现,还是会出现 501 这 样的输出信息,根据之前的描述读者可能会第一时间想到他们两个用到的锁不是同一把锁, 因此我们将代码在次做了修改

public class TicketWindow3 implements Runnable {

    private static int max_value = 0;

    private boolean flag = true;

    @Override
public void run() {
if (flag) {
while (true) {
//同步函数其实用到的锁就是 this 锁, this锁针对的是对象
//静态锁,锁是类的字节码信息,因此如果一个类的函数为静态方法,那么我们需要通过该类的 class 信息进行加锁;
synchronized (TicketWindow3.class) {
if (max_value > 500) {
break;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + ":lock..." + max_value++);
}
}
} else {
while (true)
if (ticket())
break;
} } private synchronized static boolean ticket() {
if (max_value > 500) {
return true;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + ": method.." + max_value++);
return false;
} public void change() throws InterruptedException {
Thread.sleep(30);// 读者可以自行思考为什么要sleep
this.flag = false;
} }

静态锁,锁是类的字节码信息,因此如果一个类的函数为静态方法,那么我们需要通过 该类的 class 信息进行加锁;

this 锁与 static 锁的更多相关文章

  1. 类锁和对象锁,synchronized修饰static方法与非static方法的区别

    当synchronized修饰一个static方法时,多线程下,获取的是类锁(即Class本身,注意:不是实例), 作用范围是整个静态方法,作用的对象是这个类的所有对象. 当synchronized修 ...

  2. 可重入锁 公平锁 读写锁、CLH队列、CLH队列锁、自旋锁、排队自旋锁、MCS锁、CLH锁

    1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这 ...

  3. Java核心知识点学习----线程中如何创建锁和使用锁 Lock,设计一个缓存系统

    理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...

  4. Java锁之自旋锁详解

    锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) .这些已经写好提供的锁为我们开发提供了便利,但是锁的具体性质以及类 ...

  5. java synchronized类锁,对象锁详解(转载)

    觉得还不错 留个记录,转载自http://zhh9106.iteye.com/blog/2151791 在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看 ...

  6. mysql的锁--行锁,表锁,乐观锁,悲观锁

    一 引言--为什么mysql提供了锁 最近看到了mysql有行锁和表锁两个概念,越想越疑惑.为什么mysql要提供锁机制,而且这种机制不是一个摆设,还有很多人在用.在现代数据库里几乎有事务机制,aci ...

  7. Hibernate、乐观锁和悲观锁

    悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传统的关系型数据 ...

  8. Java类锁和对象锁实践(good)

    一.前言 之前对类锁和对象锁是否是互斥的不是太确定,因此决定编写相关的程序进行实践一下.编写前对相关定义约定约定如下: 1. 类锁:在代码中的方法上加了static和synchronized的锁,或者 ...

  9. 【试验局】ReentrantLock中非公平锁与公平锁的性能测试

    硬件环境: CPU:AMD Phenom(tm) II X4 955 Processor Memory:8G SSD(128G):/ HDD(1T):/home/ 软件环境: OS:Ubuntu14. ...

随机推荐

  1. python中while循环运算符及格式化输出

    一,while循环 while 条件: while语句块(循环体) 运行: 判断你给的条件是否为真,如果真则执行循环体.否则跳出循环. 执行完循环体之后再次判断条件是否为真 例子1 我们玩联盟的时候喷 ...

  2. springboot学习之授权Spring Security

    SpringSecurity核心功能:认证.授权.攻击防护(防止伪造身份) 涉及的依赖如下: <dependency> <groupId>org.springframework ...

  3. Spotlight 监控Linux服务器的性能

    Spotlight功能:详细的进程跟踪功能远程连接在线的Unix/Linux的调优指南事件日志跟踪配置警报 详细的进程跟踪功能:Spotlight对具体的Unix / Linux的进程长达24小时的历 ...

  4. VC.时间(网页内容收集)

    1.VC++获得当前系统时间的几种方案_记忆53秒_新浪博客.html(http://blog.sina.com.cn/s/blog_676271a60101i0hb.html) 1.1.内容保存: ...

  5. img 下方的4px像素问题

    问题:在一个div块里面放了一个图片,图片下面有内容,可以不管怎么调试,在火狐浏览器,IE6下.图片img底部多出了4个像素 解决:img样式中   vertical-align: top/middl ...

  6. 《剑指offer》第五十二题(两个链表的第一个公共结点)

    // 面试题52:两个链表的第一个公共结点 // 题目:输入两个链表,找出它们的第一个公共结点. #include <iostream> #include "List.h&quo ...

  7. JS中innerHTML、outerHTML、innerText 、outerText、value的区别与联系?jQuery中的text()、html()和val()

    一.JS中innerHTML.outerHTML.innerText .outerText.value的区别与联系?jS中设置或者获取所选内容的值:①innerHTML :属性设置或返回该标签内的HT ...

  8. 解决ios下的微信页面背景音乐无法自动播放问题

    在做各种html5场景页面的时候,插入背景音乐是一个很普遍的需求,我们都知道,ios下的safari是无法自动播放音乐的,以至于现在行程一种认知,ios是没有办法自动播放媒体资源的,这个认知其实是错误 ...

  9. Subordinates CodeForces - 737C (树,构造)

    大意: 求构造一棵树, 每个节点回答它的祖先个数, 求最少打错次数. 挺简单的一个构造, 祖先个数等价于节点深度, 所以只需要确定一个最大深度然后贪心即可. 需要特判一下根的深度, 再特判一下只有一个 ...

  10. SWUST OJ(953)

    单链表的删除操作的实现 #include <stdio.h> #include <stdlib.h> typedef struct LinkNode //单链表节点结构的定义 ...