synchronized(this)的一些理解

一、当两个并发线程访问同一个对象 object 中的这个 synchronized(this) 同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

二、然而,当一个线程访问 object 的一个 synchronized(this) 同步代码块时,另一个线程仍然可以访问该 object 中的非 synchronized(this) 同步代码块。

三、尤其关键的是,当一个线程访问 object 的一个 synchronized(this) 同步代码块时,其他线程对 object 中所有其它 synchronized(this) 同步代码块的访问将被阻塞。

四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问 object 的一个 synchronized(this) 同步代码块时,它就获得了这个 object 的对象锁。结果,其它线程对该 object 对象所有同步代码部分的访问都被暂时阻塞。

五、以上规则对其它对象锁同样适用 .

举例说明:

一、当两个并发线程访问同一个对象 object 中的这个 synchronized(this) 同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

public class Thread1 implements Runnable {
       public void run() {
             synchronized(this) {
                   for (int i = 0; i < 5; i++) {
                       System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
                         }
                  }
       }

        public static void main(String[] args) {
              Thread1 t1 = new Thread1();
              Thread ta = new Thread(t1, "A");
              Thread tb = new Thread(t1, "B");
               ta.start();
               tb.start();
       }
}

结果:
A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
A synchronized loop 3
A synchronized loop 4
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4


二、然而,当一个线程访问 object 的一个 synchronized(this) 同步代码块时,另一个线程仍然可以访问该 object 中的非 synchronized(this) 同步代码块。

public class Thread2 {
       public void m4t1() {
           synchronized(this) {
                 int i = 5;
                 while( i-- > 0) {
                        System.out.println(Thread.currentThread().getName() + " : " + i);
                 try {
                      Thread.sleep(500);
                  } catch (InterruptedException ie) { }
              }
          }
     }
        public void m4t2() {
              int i = 5;
              while( i-- > 0) {
                     System.out.println(Thread.currentThread().getName() + " : " + i);
              try {
                    Thread.sleep(500);
              } catch (InterruptedException ie) { }
         }

}
       public static void main(String[] args) {
               final Thread2  myt2 = new Thread2();
               Thread  t1 = new Thread(new Runnable() {
                                              public void run() {
                                                        myt2.m4t1();
                                                 }
                     }, "t1");
                Thread  t2 = new Thread(new Runnable() {
                                              public void run() {
                                                        myt2.m4t2();
                                                 }
                     }, "t2");
                t1.start();
                t2.start();
           }
}

结果:

t1 : 4
t2 : 4
t1 : 3
t2 : 3
t1 : 2
t2 : 2
t1 : 1
t2 : 1
t1 : 0
t2 : 0

三、尤其关键的是,当一个线程访问 object 的一个 synchronized(this) 同步代码块时,其他线程对 object 中所有其它 synchronized(this) 同步代码块的访问将被阻塞

//
修改 Thread2.m4t2() 方法:

public void m4t2() {
      synchronized(this) {
          int i = 5;
          while( i-- > 0) {
          System.out.println(Thread.currentThread().getName() + " : " + i);
          try {
               Thread.sleep(500);
          } catch (InterruptedException ie) {   }
    }
}

}




结果:

t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0
t2 : 4
t2 : 3
t2 : 2
t2 : 1
t2 : 0



四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问 object 的一个 synchronized(this) 同步代码块时,它就获得了这个 object 的对象锁。结果,其它线程对该 object 对象所有同步代码部分的访问都被暂时阻塞。



//
修改 Thread2.m4t2() 方法如下:

public synchronized void m4t2() {
         int i = 5;
         while( i-- > 0) {
               System.out.println(Thread.currentThread().getName() + " : " + i);
         try {
              Thread.sleep(500);
              } catch (InterruptedException ie) { }
      }
}


结果:

t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0
t2 : 4
t2 : 3
t2 : 2
t2 : 1
t2 : 0

五、以上规则对其它对象锁同样适用 :

package ths;

public class Thread3 {
                class Inner {
                         private void m4t1() {
                         int i = 5;
                         while(i-- > 0) {
                                System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i);
                                try {
                                     Thread.sleep(500);
                                 }
                                catch(InterruptedException ie) { }
                         }
                    }

               private void m4t2() {
                        int i = 5;
                        while(i-- > 0) {
                                System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
                                   try {
                                        Thread.sleep(500);
                                    }
                                   catch(InterruptedException ie) { }
                               }
                 }
     }
             
              private void m4t1(Inner inner) {
                          synchronized(inner) { //
使用对象锁
                                       inner.m4t1();
                            }
               }

              private void m4t2(Inner inner) {
                            inner.m4t2();
               }
       
              public static void main(String[] args) {
                           final Thread3 myt3 = new Thread3();
                           final Inner inner = myt3.new Inner();
                          
                           Thread t1 = new Thread(new Runnable() {
                                                public void run() {
                                                         myt3.m4t1(inner);
                                                 }}, "t1");
                           Thread t2 = new Thread(new Runnable() {
                                                public void run() {
                                                         myt3.m4t2(inner);
                                                 }}, "t2");
                           t1.start();
                           t2.start();
            }
}


结果:

尽管线程 t1 获得了对 Inner 的对象锁,但由于线程 t2 访问的是同一个 Inner 中的非同步部分。所以两个线程互不干扰。

t1 : Inner.m4t1()=4
t2 : Inner.m4t2()=4
t1 : Inner.m4t1()=3
t2 : Inner.m4t2()=3
t1 : Inner.m4t1()=2
t2 : Inner.m4t2()=2
t1 : Inner.m4t1()=1
t2 : Inner.m4t2()=1
t1 : Inner.m4t1()=0
t2 : Inner.m4t2()=0

现在在 Inner.m4t2() 前面加上 synchronized



private synchronized void m4t2() {
            int i = 5;
            while(i-- > 0) {
              System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
                 try {
                      Thread.sleep(500);
                 }
                catch(InterruptedException ie) {}
                }
     }



结果:

尽管线程 t1 t2 访问了同一个 Inner 对象中两个毫不相关的部分 , 但因为 t1 先获得了对 Inner 的对象锁,所以 t2 Inner.m4t2() 的访问也被阻塞,因为 m4t2() Inner 中的一个同步方法。

t1 : Inner.m4t1()=4
t1 : Inner.m4t1()=3
t1 : Inner.m4t1()=2
t1 : Inner.m4t1()=1
t1 : Inner.m4t1()=0
t2 : Inner.m4t2()=4
t2 : Inner.m4t2()=3
t2 : Inner.m4t2()=2
t2 : Inner.m4t2()=1
t2 : Inner.m4t2()=0

 

你可能感兴趣的:(职场,休闲)