Android学习 (七)synchronized(一)(转)

转载 2012年03月29日 14:27:59

转自: http://hi.baidu.com/fenghuang1207/blog/item/06a17dce8534ff1d93457e21.html


  synchronized:Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

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

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

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

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

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

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

package ths;

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 = newThread1();  
         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)同步代码块。

package ths;

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 = newThread2();  
         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


相关文章推荐

并发编程学习总结(七) :java中synchronized关键字使用详解(1)

上一篇中学习了显示锁ReentrantLock和其条件对象Condition的使用,下面小小的总结一下: (1) 锁用来保护代码片段,任何时刻只能有一个线程执行被保护的代码片段 (2) 锁可以管理试图...

synchronized(内部锁)关键字——线程学习七

锁用来保护代码片段,任何时刻只能有一个线程执行被保护的代码。锁可以管理试图进入被保护代码段的线程。锁可以拥有一个或是多个相关的条件对象。每个条件对象管理那些已经进入被保护的代码段但还不能运行的线程。 ...

java synchronized 学习

  • 2016年12月03日 12:06
  • 824KB
  • 下载

Android 同步代码块,synchronized加锁

以车站售票为例,多个线程不能同时买一张票,所以把买票这个代码块加锁,等待前面线程买好了,后面线程才能进入买票 class BuyTicket implements Runnable { pri...
  • Pansing
  • Pansing
  • 2015年07月13日 16:05
  • 2528

Android同步锁:Synchronized的小实验

今天在看博客的时候突然遇到了同步代码块——Synchronized,猛然间想到自己这次面试的时候面试官特意问了关于java线程同步锁的问题,当时自己也是知道那么一点单例模式,就主要聊了下单例模式,而同...

Android进阶——多线程系列之wait、notify、sleep、join、yield、synchronized关键字、ReentrantLock锁

多线程系列之线程的wait、Sleep、join、yield、synchronized关键字、ReentrantLock锁

Android线程—synchronized与Lock

java中使用锁的两个基本工具是 synchronized 和 Lock。 1.synchronized既可以同步方法也可以同步代码块 // 同步的方法 pu...

Android synchronized用法

在网上看了不少介绍Java 多线程同步的文章,如下两篇文章行文清楚,算是帮我解了疑惑。原文链接如下: 《android-线程同步》:http://blog.csdn.net/winson_jason/...
  • chwnpp2
  • chwnpp2
  • 2015年02月26日 18:13
  • 576

Android/JAVA 笔记 同步操作/synchronized / wait()/ notify()

synchronized编写程序离不开多线程操作。而多线程又离不开同步操作。这是很重要的。java语言有一个关键词synchronized可以应多同步操作。之前学习的时候我没有怎么去理解这个东西。最近...

Android并发编程之如何使用ReentrantReadWriteLock替代synchronized来提高程序的效率

Java的synchronized关键字可以帮助我们解决多线程并发的问题,比如我们有一个公共资源,多个线程都来操作这个公共的资源,就会出现并发的问题,比如不同的线程对同一个数据同时进行读和写,肯定会使...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android学习 (七)synchronized(一)(转)
举报原因:
原因补充:

(最多只允许输入30个字)