Java多线程系列--“基础篇”04之 synchronized关键字(二)

2014-11-24 03:24:23 · 作者: · 浏览: 10
2的执行流程是不是和Demo1_1一样呢?
运行结果:
复制代码
t1 loop 0
t2 loop 0
t1 loop 1
t2 loop 1
t1 loop 2
t2 loop 2
t1 loop 3
t2 loop 3
t1 loop 4
t2 loop 4
复制代码
结果说明:
如果这个结果一点也不令你感到惊讶,那么我相信你对synchronized和this的认识已经比较深刻了。否则的话,请继续 阅读这里的分析。
synchronized(this)中的this是指“当前的类对象”,即synchronized(this)所在的类对应的当前对象。它的作用是获取“当前对象的同步锁”。
对于Demo1_2中,synchronized(this)中的this代表的是MyThread对象,而t1和t2是两个不同的MyThread对象,因此t1和t2在执行synchronized(this)时,获取的是不同对象的同步锁。对于Demo1_1对而言,synchronized(this)中的this代表的是MyRunable对象;t1和t2共同一个MyRunable对象,因此,一个线程获取了对象的同步锁,会造成另外一个线程等待。
第二条
当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程仍然可以访问“该对象”的非同步代码块。
下面是“synchronized代码块”对应的演示程序。
复制代码
1 class Count {
2
3 // 含有synchronized同步块的方法
4 public void synMethod() {
5 synchronized(this) {
6 try {
7 for (int i = 0; i < 5; i++) {
8 Thread.sleep(100); // 休眠100ms
9 System.out.println(Thread.currentThread().getName() + " synMethod loop " + i);
10 }
11 } catch (InterruptedException ie) {
12 }
13 }
14 }
15
16 // 非同步的方法
17 public void nonSynMethod() {
18 try {
19 for (int i = 0; i < 5; i++) {
20 Thread.sleep(100);
21 System.out.println(Thread.currentThread().getName() + " nonSynMethod loop " + i);
22 }
23 } catch (InterruptedException ie) {
24 }
25 }
26 }
27
28 public class Demo2 {
29
30 public static void main(String[] args) {
31 final Count count = new Count();
32 // 新建t1, t1会调用“count对象”的synMethod()方法
33 Thread t1 = new Thread(
34 new Runnable() {
35 @Override
36 public void run() {
37 count.synMethod();
38 }
39 }, "t1");
40
41 // 新建t2, t2会调用“count对象”的nonSynMethod()方法
42 Thread t2 = new Thread(
43 new Runnable() {
44 @Override
45 public void run() {
46 count.nonSynMethod();
47 }
48 }, "t2");
49
50
51 t1.start(); // 启动t1
52 t2.start(); // 启动t2
53 }
54 }
复制代码
运行结果:
复制代码
t1 synMethod loop 0
t2 nonSynMethod loop 0
t1 synMethod loop 1
t2 nonSynMethod loop 1
t1 synMethod loop 2
t2 nonSynMethod loop 2
t1 synMethod loop 3
t2 nonSynMethod loop 3
t1 synMethod loop 4
t2 nonSynMethod loop 4
复制代码
结果说明:
主线程中新建了两个子线程t1和t2。t1会调用count对象的synMethod()方法,该方法内含有同步块;而t2则会调用count对象的nonSynMethod()方法,该方法不是同步方法。t1运行时,虽然调用synchronized(this)获取“count的同步锁”;但是并没有造成t2的阻塞,因为t2没有用到“count”同步锁。
第三条
当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的其他的“synchronized方法”或者“synchronized代码块”的访问将被阻塞。
我们将上面的例子中的nonSynMethod()方法体的也用synchronized(this)修饰。修改后的源码如下:
复制代码
1 class Count {
2
3 // 含有synchronized同步块的方法
4 public void synMethod() {
5 synchronized(this) {
6 try {
7 for (int i = 0; i < 5; i++) {
8 Thread.sleep(100); // 休眠100ms
9 System.out.println(Thread.currentThread().getName() + " synMethod loop " + i);
10 }
11 } catch (InterruptedException ie) {
12 }
13 }
14 }
15
16 // 也包含synchr