Java synchronized再研究

来源:互联网 发布:淘宝装米礼品盒 编辑:程序博客网 时间:2024/05/16 00:54

在CSDN上看到了一篇关于synchronized的文章,突然发现自己也是很少使用它的,突然对它的研究产生了兴趣。更改了一下原作者的代码,先贴上来,我在写研究结果。

  1. package com.blueflash.study;
  2. public class MainThread {
  3.     public static void main(String args[]) throws Exception{
  4.         SecondThread sb=new SecondThread();
  5.         sb.start();
  6.         System.out.println("Second Thread start");
  7.         synchronized (sb) {
  8.             try{
  9.                 System.out.println("Waiting.......");
  10.                 sb.wait();//等待SecondThread完成后通知主线程继续往下执行
  11.                 System.out.println("Second Thread Complete");
  12.             }catch(Exception ex){
  13.                 ex.printStackTrace();
  14.             }
  15.             System.out.println("Main Thread Complete");
  16.         }
  17.     }
  18. }
  19. class SecondThread extends Thread{
  20.     public void run() {
  21.         synchronized (this) {
  22.             try{
  23.             System.out.println("Second Thread Running");
  24.             Thread.currentThread().sleep(5000);
  25.             }catch(Exception ex){
  26.                 ex.printStackTrace();
  27.             }
  28.             notify();
  29.         }
  30.     }
  31. }

好了,我连续运行了这个程序N次,结果都不相同。我们来看看结果有哪些:

第一种结果:

Second Thread start
Waiting.......
Second Thread Running
Second Thread Complete
Main Thread Complete

 

第二种结果:

Second Thread start
Second Thread Running
Waiting.......
PS:程序一直在这里挂起来了,因为执行到了sb.wait(),但是没有notify()来唤醒。

 

第三种结果:

Second Thread Running
Second Thread start
Waiting.......
Second Thread Complete
Main Thread Complete

PS:跟第二种结果比较,这次程序没有被挂起,而是执行完毕了。

 

通过三种结果,不难发现,同一个对象实例的不同线程只能执行其中一个synchronized方法或者块。并且具体执行到了哪一个synchronized块不是由程序所决定,而是随机的,两个线程是并发的,所以,就好像先到先得一样,谁先执行到了synchronized块,谁就先取得对象锁。第一种结果我们看到,主线程首先到达了synchronized块,于是SecondThread被阻塞,直到主线程条用了wait方法使自己睡眠,让SecondThread有机会执行,直到SecondThread把主线程唤醒(notify())。

二,三种结果就比较好玩了,就像在比赛跑一样。这里首先是SecondThread跑的比较快,取得了对象锁,让主线程不能继续往下执行,被挂在主线程的synchronized块位置,当SecondThread执行完了synchronized块后,两个线程又并发执行了,注意看SecondThread的notify()方法是在synchronized块外面的,这个时候,他们又开始最后的冲刺了,看是主线程先导wait还是SecondThread先到notify。如果主线程先到,那么程序能顺利的执行完毕,因为它wait之后,又立马被唤醒,如果SecondThread先到,很不幸,结束任务吧,它会沉睡不醒了。

原创粉丝点击