在Java中,每一个线程都有一个内部锁。当我们使用synchronized关键字时,就是利用这个内部锁来实现线程对某个对象的锁定控制。

那么,如果某个对象中有两个方法,方法一和方法二都使用了synchronized关键字。如果线程一执行该对象的方法一,线程二执行该对象的方法二。如果线程1一直不释放该对象的内部锁的话,那么线程二应该无法执行该对象的方法二。下面就用代码来验证一下。

首先,定义一个Task类。

 

 1 package corejava.chapter14;
 2 
 3 public class TaskC {
 4 
 5     public synchronized void method1() throws InterruptedException {
 6 
 7         while (true) {
 8             System.out.println("我是方法1");
 9             Thread.sleep(10000);
10         }
11 
12     }
13 
14     public synchronized void method2() throws InterruptedException {
15 
16         while (true) {
17             System.out.println("我是方法2");
18             Thread.sleep(10000);
19         }
20 
21     }
22 
23 }

method1每隔10秒就会输出一句“我是方法1”。method2每隔10秒就会输出一句“我是方法2”。两个方法都使用了synchronized关键字。

再定义两个执行类ExecutorC1和Executor2。

 1 package corejava.chapter14;
 2 
 3 public class ExecutorC1 implements Runnable {
 4 
 5     private TaskC taskC;
 6 
 7     public ExecutorC1(TaskC taskC) {
 8         this.taskC = taskC;
 9     }
10 
11     @Override
12     public void run() {
13         try {
14             taskC.method1();
15         } catch (Exception e) {
16             e.printStackTrace();
17         }
18 
19     }
20 }
 1 package corejava.chapter14;
 2 
 3 public class ExecutorC2 implements Runnable {
 4 
 5     private TaskC taskC;
 6 
 7     public ExecutorC2(TaskC taskC) {
 8         this.taskC = taskC;
 9     }
10 
11     @Override
12     public void run() {
13         try {
14             taskC.method2();
15         } catch (Exception e) {
16             e.printStackTrace();
17         }
18 
19     }
20 
21 }

执行类1启动线程后,会执行taskC的method1方法。执行类启动线程后,会执行taskC的method2方法。

最后定义入口类Main

 1 package corejava.chapter14;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) {
 6         TaskC taskC = new TaskC();
 7         ExecutorC1 executorC1 = new ExecutorC1(taskC);
 8         ExecutorC2 executorC2 = new ExecutorC2(taskC);
 9         Thread thread1 = new Thread(executorC1);
10         Thread thread2 = new Thread(executorC2);
11         thread1.start();
12         thread2.start();
13     }
14 
15 }

执行对象1和执行对象2都使用同一个taskC去实例化,这样他们之间就会存在竞争。当thread1执行taskC的method1时,会一直持有taskC的内部锁,因此thread2将一直处于阻塞状态。

下面是运行输出结果

可见,确实如我们所料,虽然两个线程要执行的是不同的方法,但因为线程1一直“霸占”着内部锁,所以线程2始终在阻塞状态,得不到执行。

所以,如果我们在对某个类要使用synchronized关键字进行锁定控制时,一定要牢记它使用的是该类的内部锁。它是唯一的。当多个方法都用它来进行控制时,一定要考虑这一点。

posted on 2016-09-10 17:57  t1t1t1  阅读(204)  评论(0)    收藏  举报