android开发之synchronized的用法

android开发之synchronized的用法


在android开发中synchronized主要有四种用法。第一是在方法声明时使用;第二是在对某一代码块时使用;第三是对某一对象使用;第四是对某一类使用。具体的实现代码如下:



 1.方法声明时使用

放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入.
 
      例如:

技术分享      public synchronized void synMethod() {
技术分享        
//方法体
技术分享
      }

  

  2.对某一代码块使用

synchronized后跟括号,括号里是变量,这样,一次只有一个线程进入该代码块.此时,线程获得的是成员锁.例如:

技术分享      public int synMethod(int a1){
技术分享        synchronized(a1) 
{
技术分享          
//一次只能有一个线程进入
技术分享
        }

技术分享      }


    3.对某一对象使用

synchronized后面括号里是一对象,此时,线程获得的是对象锁.例如:

 

技术分享 public class MyThread implements Runnable {
技术分享    
public static void main(String args[]) {
技术分享    MyThread mt 
= new MyThread();
技术分享    Thread t1 
= new Thread(mt, "t1");
技术分享    Thread t2 
= new Thread(mt, "t2");
技术分享    Thread t3 
= new Thread(mt, "t3");
技术分享    Thread t4 
= new Thread(mt, "t4");
技术分享    Thread t5 
= new Thread(mt, "t5");
技术分享    Thread t6 
= new Thread(mt, "t6");
技术分享    t1.start();
技术分享    t2.start();
技术分享    t3.start();
技术分享    t4.start();
技术分享    t5.start();
技术分享    t6.start();
技术分享  }

技术分享
技术分享  
public void run() {
技术分享    synchronized (
this{
技术分享      System.
out.println(Thread.currentThread().getName());
技术分享    }

技术分享  }

技术分享}
 
技术分享 
技术分享
技术分享

 
    对于3,如果线程进入,则得到当前对象锁,那么别的线程在该类所有对象上的任何操作都不能进行.在对象级使用锁通常是一种比较粗糙的方法。为什么要将整个对象都上锁,而不允许其他线程短暂地使用对象中其他同步方法来访问共享资源?如果一个对象拥有多个资源,就不需要只为了让一个线程使用其中一部分资源,就将所有线程都锁在外面。由于每个对象都有锁,可以如下所示使用虚拟对象来上锁:

 

技术分享 class FineGrainLock {
技术分享
技术分享   MyMemberClass x, y;
技术分享   Object xlock 
= new Object(), ylock = new Object();
技术分享
技术分享   
public void foo() {
技术分享      synchronized(xlock) 
{
技术分享         
//access x here
技术分享
      }

技术分享
技术分享      
//do something here - but don‘t use shared resources
技术分享

技术分享      synchronized(ylock) 
{
技术分享         
//access y here
技术分享
      }

技术分享   }

技术分享
技术分享   
public void bar() {
技术分享      synchronized(
this{
技术分享         
//access both x and y here
技术分享
      }

技术分享      
//do something here - but don‘t use shared resources
技术分享
   }

技术分享  }

技术分享
技术分享


     4.对类使用时

synchronized后面括号里是类,此时,线程获得的是对象锁.例如:

 

技术分享class ArrayWithLockOrder{
技术分享  
private static long num_locks = 0;
技术分享  
private long lock_order;
技术分享  
private int[] arr;
技术分享
技术分享  
public ArrayWithLockOrder(int[] a)
技术分享  
{
技术分享    arr 
= a;
技术分享    synchronized(ArrayWithLockOrder.
class{//-----这里
技术分享
      num_locks++;             // 锁数加 1。
技术分享

技术分享      lock_order 
= num_locks;  // 为此对象实例设置唯一的 lock_order。
技术分享
    }

技术分享  }

技术分享  
public long lockOrder()
技术分享  
{
技术分享    
return lock_order;
技术分享  }

技术分享  
public int[] array()
技术分享  
{
技术分享    
return arr;
技术分享  }

技术分享  }

技术分享
技术分享  
class SomeClass implements Runnable
技术分享 
{
技术分享  
public int sumArrays(ArrayWithLockOrder a1,
技术分享                       ArrayWithLockOrder a2)
技术分享  
{
技术分享    
int value = 0;
技术分享    ArrayWithLockOrder first 
= a1;       // 保留数组引用的一个
技术分享
    ArrayWithLockOrder last = a2;        // 本地副本。
技术分享
    int size = a1.array().length;
技术分享    
if (size == a2.array().length)
技术分享    
{
技术分享      
if (a1.lockOrder() > a2.lockOrder())  // 确定并设置对象的锁定
技术分享
      {                                     // 顺序。
技术分享
        first = a2;
技术分享        last 
= a1;
技术分享      }

技术分享      synchronized(first) 
{              // 按正确的顺序锁定对象。
技术分享
        synchronized(last) {
技术分享          
int[] arr1 = a1.array();
技术分享          
int[] arr2 = a2.array();
技术分享          
for (int i=0; i<size; i++)
技术分享            value 
+= arr1[i] + arr2[i];
技术分享        }

技术分享      }

技术分享    }

技术分享    
return value;
技术分享
技术分享  }

技术分享  
public void run() {
技术分享    
//技术分享
技术分享
  }

技术分享  }

技术分享
技术分享

  
    对于4,如果线程进入,则线程在该类中所有操作不能进行,包括静态变量和静态方法,实际上,对于含有静态方法和静态变量的代码块的同步,我们通常用4来加锁.

以上为synchronized的四种用法。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。