从头认识多线程-2.2 synchronized持有对象锁与类锁的相同点
来源:互联网 发布:美工兼职 编辑:程序博客网 时间:2024/05/19 01:13
这一章节我们来讨论一下synchronized持有对象锁与类锁的相同点。
1.当所有方法都不使用同步的时候
代码清单
package com.ray.deepintothread.ch02.topic_2;public class SynchInstance1 {public static void main(String[] args) throws InterruptedException {MyTestObjectOne myTestObjectOne = new MyTestObjectOne();for (int i = 0; i < 5; i++) {ThreadOne threadTwo = new ThreadOne(myTestObjectOne);Thread thread = new Thread(threadTwo);thread.setName("" + i);thread.start();}}}class ThreadOne implements Runnable {private MyTestObjectOne myTestObjectOne;public ThreadOne(MyTestObjectOne myTestObjectOne) {this.myTestObjectOne = myTestObjectOne;}@Overridepublic void run() {try {if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {myTestObjectOne.test1();} else {myTestObjectOne.test2();}} catch (InterruptedException e) {e.printStackTrace();}}}class MyTestObjectOne {public void test1() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test1 begin");System.out.println(Thread.currentThread().getName() + " method test1 waiting");Thread.sleep(200);System.out.println(Thread.currentThread().getName() + " method test1 end");}public void test2() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test2 begin");System.out.println(Thread.currentThread().getName() + " method test2 waiting");Thread.sleep(200);System.out.println(Thread.currentThread().getName() + " method test2 end");}}
输出:
0 method test1 begin
0 method test1 waiting
4 method test1 begin
4 method test1 waiting
2 method test1 begin
2 method test1 waiting
1 method test2 begin
1 method test2 waiting
3 method test2 begin
3 method test2 waiting
0 method test1 end
4 method test1 end
2 method test1 end
1 method test2 end
3 method test2 end
持有类锁的情况:
package com.ray.deepintothread.ch02.topic_3;public class SynchInstance1 {public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 5; i++) {ThreadOne threadTwo = new ThreadOne();Thread thread = new Thread(threadTwo);thread.setName("" + i);thread.start();}}}class ThreadOne implements Runnable {@Overridepublic void run() {try {if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {MyTestObjectOne.test1();} else {MyTestObjectOne.test2();}} catch (InterruptedException e) {e.printStackTrace();}}}class MyTestObjectOne {public static void test1() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test1 begin");System.out.println(Thread.currentThread().getName() + " method test1 waiting");Thread.sleep(200);System.out.println(Thread.currentThread().getName() + " method test1 end");}public static void test2() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test2 begin");System.out.println(Thread.currentThread().getName() + " method test2 waiting");Thread.sleep(200);System.out.println(Thread.currentThread().getName() + " method test2 end");}}
输出:
0 method test1 begin
0 method test1 waiting
2 method test1 begin
2 method test1 waiting
3 method test2 begin
3 method test2 waiting
1 method test2 begin
1 method test2 waiting
4 method test1 begin
4 method test1 waiting
2 method test1 end
3 method test2 end
0 method test1 end
1 method test2 end
4 method test1 end
从两个输出可以看见,方法是交叉的执行,没有任何同步在里面的
2.当所有方法都使用同步的时候
代码清单
package com.ray.deepintothread.ch02.topic_2;public class SynchInstance2 {public static void main(String[] args) throws InterruptedException {MyTestObjectTwo myTestObjectTwo = new MyTestObjectTwo();for (int i = 0; i < 5; i++) {ThreadTwo threadTwo = new ThreadTwo(myTestObjectTwo);Thread thread = new Thread(threadTwo);thread.setName("" + i);thread.start();}}}class ThreadTwo implements Runnable {private MyTestObjectTwo myTestObjectTwo;public ThreadTwo(MyTestObjectTwo myTestObjectTwo) {this.myTestObjectTwo = myTestObjectTwo;}@Overridepublic void run() {try {if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {myTestObjectTwo.test1();} else {myTestObjectTwo.test2();}} catch (InterruptedException e) {e.printStackTrace();}}}class MyTestObjectTwo {public synchronized void test1() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test1 begin");System.out.println(Thread.currentThread().getName() + " method test1 waiting");System.out.println(Thread.currentThread().getName() + " method test1 end");}public synchronized void test2() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test2 begin");System.out.println(Thread.currentThread().getName() + " method test2 waiting");System.out.println(Thread.currentThread().getName() + " method test2 end");}}
输出:
1 method test2 begin
1 method test2 waiting
1 method test2 end
0 method test1 begin
0 method test1 waiting
0 method test1 end
2 method test1 begin
2 method test1 waiting
2 method test1 end
4 method test1 begin
4 method test1 waiting
4 method test1 end
3 method test2 begin
3 method test2 waiting
3 method test2 end
package com.ray.deepintothread.ch02.topic_3;public class SynchInstance2 {public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 5; i++) {ThreadTwo threadTwo = new ThreadTwo();Thread thread = new Thread(threadTwo);thread.setName("" + i);thread.start();}}}class ThreadTwo implements Runnable {@Overridepublic void run() {try {if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {MyTestObjectTwo.test1();} else {MyTestObjectTwo.test2();}} catch (InterruptedException e) {e.printStackTrace();}}}class MyTestObjectTwo {public static synchronized void test1() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test1 begin");System.out.println(Thread.currentThread().getName() + " method test1 waiting");System.out.println(Thread.currentThread().getName() + " method test1 end");}public static synchronized void test2() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test2 begin");System.out.println(Thread.currentThread().getName() + " method test2 waiting");System.out.println(Thread.currentThread().getName() + " method test2 end");}}
输出:
0 method test1 begin
0 method test1 waiting
0 method test1 end
1 method test2 begin
1 method test2 waiting
1 method test2 end
3 method test2 begin
3 method test2 waiting
3 method test2 end
2 method test1 begin
2 method test1 waiting
2 method test1 end
4 method test1 begin
4 method test1 waiting
4 method test1 end
从输出和debug发现,每一个方法都是按照顺序执行,同步起效
但是比较奇怪的是,每次都是整个方法执行完了才到下一个方法执行
按照平常的执行,应该是像上面一样,交叉的执行,因为我们使用多线程而且是访问不同的方法,如果同步是方法级别,应该可以想象到线程1访问test1的时候,我线程2同时可以访问test2,如果不是,那么synchronized持有的是锁不是方法级别的,而是对象级别或者类级别,而一般类级别对于的是静态方法和代码块。
3.特点
(1)所有同步方法只能按顺序执行,上面的例子有所演示
(2)synchronized只同步标记的方法,不标记的还是不同步
package com.ray.deepintothread.ch02.topic_2;public class SynchInstance3 {public static void main(String[] args) throws InterruptedException {MyTestObjectThree myTestObjectThree = new MyTestObjectThree();for (int i = 0; i < 5; i++) {ThreadThree threadThree = new ThreadThree(myTestObjectThree);Thread thread = new Thread(threadThree);thread.setName("" + i);thread.start();}}}class ThreadThree implements Runnable {private MyTestObjectThree myTestObjectThree;public ThreadThree(MyTestObjectThree myTestObjectThree) {this.myTestObjectThree = myTestObjectThree;}@Overridepublic void run() {try {if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {myTestObjectThree.test1();} else {myTestObjectThree.test2();}} catch (InterruptedException e) {e.printStackTrace();}}}class MyTestObjectThree {public synchronized void test1() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test1 begin");System.out.println(Thread.currentThread().getName() + " method test1 waiting");System.out.println(Thread.currentThread().getName() + " method test1 end");}public void test2() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test2 begin");System.out.println(Thread.currentThread().getName() + " method test2 waiting");System.out.println(Thread.currentThread().getName() + " method test2 end");}}
输出:
0 method test1 begin
3 method test2 begin
3 method test2 waiting
3 method test2 end
1 method test2 begin
1 method test2 waiting
1 method test2 end
0 method test1 waiting
0 method test1 end
2 method test1 begin
2 method test1 waiting
2 method test1 end
4 method test1 begin
4 method test1 waiting
4 method test1 end
package com.ray.deepintothread.ch02.topic_3;public class SynchInstance3 {public static void main(String[] args) throws InterruptedException {MyTestObjectThree myTestObjectThree = new MyTestObjectThree();for (int i = 0; i < 5; i++) {ThreadThree threadThree = new ThreadThree(myTestObjectThree);Thread thread = new Thread(threadThree);thread.setName("" + i);thread.start();}}}class ThreadThree implements Runnable {private MyTestObjectThree myTestObjectThree;public ThreadThree(MyTestObjectThree myTestObjectThree) {this.myTestObjectThree = myTestObjectThree;}@Overridepublic void run() {try {if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {myTestObjectThree.test1();} else {myTestObjectThree.test2();}} catch (InterruptedException e) {e.printStackTrace();}}}class MyTestObjectThree {public synchronized void test1() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test1 begin");System.out.println(Thread.currentThread().getName() + " method test1 waiting");System.out.println(Thread.currentThread().getName() + " method test1 end");}public void test2() throws InterruptedException {System.out.println(Thread.currentThread().getName() + " method test2 begin");System.out.println(Thread.currentThread().getName() + " method test2 waiting");System.out.println(Thread.currentThread().getName() + " method test2 end");}}
输出:
0 method test1 begin
0 method test1 waiting
0 method test1 end
2 method test1 begin
2 method test1 waiting
2 method test1 end
1 method test2 begin
1 method test2 waiting
4 method test1 begin
4 method test1 waiting
4 method test1 end
1 method test2 end
3 method test2 begin
3 method test2 waiting
3 method test2 end
总结:这一章节我们讨论了synchronized持有锁的情况。
这一章节就到这里,谢谢
------------------------------------------------------------------------------------
我的github:https://github.com/raylee2015/DeepIntoThread
目录:http://blog.csdn.net/raylee2007/article/details/51204573
- 从头认识多线程-2.2 synchronized持有对象锁与类锁的相同点
- 从头认识多线程-2.3 synchronized持有对象锁与类锁的不同点
- 从头认识多线程-2.11 通过同步代码块证明synchronized标记的是对象锁
- 从头认识多线程-2.5 锁的可重入性
- 从头认识多线程-2.20 synchronized同步方法的无限等待与解决方法
- 多线程锁的重复持有
- 从头认识多线程-2.18 同步方法与同步静态代码块持有的是不同的锁
- 从头认识多线程-2.12 synchronized标记的方法和synchronized(this)标记的代码块锁定的是当前对象
- 从头认识多线程-2.13 synchronized ()代码块不单可以用this,也可以用其他对象
- 多线程并发 synchronized对象锁的控制与优化
- 多线程并发 synchronized对象锁的控制与优化
- 从头认识多线程-2.15 解决由同步的synchronized (newobject()) 引起的脏读的方法
- 从头认识多线程-2.14 由同步的synchronized (newobject()) 引起的异步现象和脏读
- 从头认识多线程-2.25 synchronized同步方法在jvm是怎样执行的?
- 从头认识多线程-2.26 synchronized同步代码块在jvm是怎样执行的?
- 从头认识多线程-3.3 synchronized某些解决不了的可视性问题,只能使用volatile来解决
- 从头认识多线程-1.1 多线程的创建
- Oracle 查看 对象 持有 锁 的情况
- 机器学习基石第七讲:the vc dimension
- Java并发:等待事件发生后所有线程继续执行
- LeetCode *** 79. Word Search
- java基础学习(3)
- android.webkit.WebView/WebViewClient/WebChromeClient
- 从头认识多线程-2.2 synchronized持有对象锁与类锁的相同点
- Hibernate4实战 之 第二部分:Hibernate的基本配置
- 循环队列的基本操作
- Paxos算法
- Java中的super关键字
- Shell脚本学习笔记-重定向与管道命令
- 1011-Oil Deposits
- Android webview使用详解
- [BZOJ1725][Usaco2006 Nov]Corn Fields牧场的安排(状压dp)