这一章节我们来讨论一下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; } @Override public 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 { @Override public 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; } @Override public 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 { @Override public 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; } @Override public 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; } @Override public 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