synchronized 对象锁和 ReentrantLock非公平锁tryLock() 的比较

来源:互联网 发布:skype6.6mac官方下载 编辑:程序博客网 时间:2024/05/22 12:52

看见 程序里有 Lock,ReentrantLock 表示共享数据块要用 Lock对象锁住了。

一、简单描述

1、synchronized:当没有获得锁时,一直死等,不能放弃

2、ReentrantLock ():无参数的构造器,是默认非公平锁。

    非公平锁:随时来,随时取,不管就绪队列是否已经有人了,取不到,就放弃锁。

      1>马上试一下,如果不能获得锁就放弃了,逛超市去。

      2>可以给一点时间(10分钟内),如果10分钟还没有获得锁,就逛超市去。

二、synchronized,死等,中途不能放弃

    1、图形

      

因为只有一个对象TestSyn,对应一个锁,5个驱动线程都在等,死等,中途不能放弃。

目前大家都在等待锁,就绪队列空了,cpu也空了,

     最后:t1[0] 获得锁,t1[3], t1[4], t1[2], t1[1],必须死等,不得中途放弃。

                t1[0]释放锁,才能执行锁里面的代码块。

    2、代码  

package concurrency;

public class TestSyn implements Runnable{
private int countobj=0;
   @Override  
   public void run() {   
    System.out.println(Thread.currentThread().getName()+"开始去取锁!");   
    synchronized (this)
    {             
    System.out.println(Thread.currentThread().getName()+"获得锁  countobj!"+(++countobj));
    for(int j=0;j<5;j++)
    System.out.println(Thread.currentThread().getName()+"自增!"+j); 
      }  
   }
   public static void main(String[] args) throws InterruptedException {  
    TestSyn test =new TestSyn();//一个干活线程
    Thread[] t1=new Thread[5];
    for (int i=0;i<5;i++)
    {
        t1[i]= new Thread(test);  //5个驱动线程
        t1[i].start();
    }
       System.out.println("结束");  
   }  
}  

 结果:

Thread-0开始去取锁!
Thread-3开始去取锁!
Thread-4开始去取锁!
Thread-2开始去取锁!
结束
Thread-1开始去取锁!
Thread-0获得锁  countobj!1
Thread-0自增!0
Thread-0自增!1
Thread-0自增!2
Thread-0自增!3
Thread-0自增!4
Thread-1获得锁  countobj!2
Thread-1自增!0
Thread-1自增!1
Thread-1自增!2
Thread-1自增!3
Thread-1自增!4
Thread-4获得锁  countobj!3
Thread-4自增!0
Thread-4自增!1
Thread-4自增!2
Thread-4自增!3
Thread-4自增!4
Thread-2获得锁  countobj!4
Thread-2自增!0
Thread-2自增!1
Thread-2自增!2
Thread-2自增!3
Thread-2自增!4
Thread-3获得锁  countobj!5
Thread-3自增!0
Thread-3自增!1
Thread-3自增!2
Thread-3自增!3
Thread-3自增!4 

三、Lock 对象 去锁住 共享数据代码块

    

步骤: 1、建立固定的Lock 对象  private Lock lock = new ReentrantLock();这语句存放在一个类中对应的对象,

                对应  Synchronized (obj)可以是任何对象。

           2、要用到共享数据块的前面:lock.lock(); 

          3、释放锁:finally lock.unlock();  手动释放锁,Synchronized 当代码执行完,自动释放锁。

        4 、try{  return  值;}finally{} :return 可有可无,如果想着锁慢点释放,让第二个干活线程也能看见方法返回的数据。 

 1、图形

    

这时t1[3],t1[4]同时也来取锁,肯定没有,就放弃了,就绪队列就剩下面三个线程。

剩下t1[0],t1[1],t1[2] 三个线程交叉执行。

  


 2、ReentrantLock():非公平锁

     locks.tryLock():立刻取钥匙,不停留

   package concurrency;


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestTryLcok implements Runnable{  
  private static Lock locks = new ReentrantLock();  
private int countobj=0;
   @Override  
   public void run() {     
    System.out.println(Thread.currentThread().getName()+"开始去取锁!");
    boolean captured = false;    
       try {  
        System.out.println(Thread.currentThread().getName()+"取captured前 "+captured);
        captured=locks.tryLock();
        System.out.println(Thread.currentThread().getName()+"取captured后 "+captured);
       if(captured){       
           System.out.println(Thread.currentThread().getName()+"获得锁-->");             
    System.out.println(Thread.currentThread().getName()+"countobj!"+(++countobj));
    for(int j=0;j<5;j++)
    System.out.println(Thread.currentThread().getName()+"自增:"+j); 
       }else{  
           System.out.println(Thread.currentThread().getName()+" 未获得锁--> ");  
       }            
       }finally {  
        if(captured){
        System.out.println(Thread.currentThread().getName()+" 释放锁--> ");  
           locks.unlock();
        }
       }  
   }  
 
   public static void main(String[] args) throws InterruptedException {  
    TestTryLcok test =new TestTryLcok();//一个对象
    Thread[] t1=new Thread[5];
    for (int i=0;i<5;i++)
    {
        t1[i]= new Thread(test);  //5个驱动线程
        t1[i].start();
    }
       System.out.println("结束");     
   }  
}  

结果:

Thread-0开始去取锁!
Thread-1开始去取锁!
结束
Thread-2开始去取锁!
Thread-2取captured前 false
Thread-1取captured前 false
Thread-2取captured后 true
Thread-3开始去取锁!
Thread-3取captured前 false
Thread-0取captured前 false
Thread-3取captured后 false
Thread-3 未获得锁--> 
Thread-4开始去取锁!
Thread-4取captured前 false
Thread-4取captured后 false
Thread-4 未获得锁--> 
Thread-2获得锁-->
Thread-1取captured后 false
Thread-2countobj!1
Thread-0取captured后 false
Thread-2自增:0
Thread-1 未获得锁--> 
Thread-2自增:1
Thread-0 未获得锁--> 
Thread-2自增:2
Thread-2自增:3
Thread-2自增:4
Thread-2 释放锁--> 

 

阅读全文
0 0
原创粉丝点击