synchronized和lock锁

1.synchronized是java中的一个关键字,可以使用为同步函数或者同步函数块表示同步,里面包含了锁和解锁的过程,只允许一个线程进入,调用的是JVM内部的方法。lock锁是java1.5后新增加的一种类,也可以锁线程,但是需要用lock()和unlock手动上锁和解锁,调用的是通过static 内部类sync来进行锁操作

2.synchronized中一旦对一个线程上锁,其他竞争的线程都会处于等待状态无法操作。而用lock上锁可以使用tryLock方法,获取锁失败时返回false,这样没有竞争获得锁的线程也可以执行其它的操作, 而不至于使线程进入休眠。也可以限定处于竞争锁队列的时间,更加灵活。

3.synchronized中的notify(),wait()不能唤醒和等待特定的线程。而lock锁提供了一个方法可以创建多个Condition对象,这个对象同样可以使用await(),signal()唤醒和等待线程,这样多线程时就可以指定对一类相同类型线程进行唤醒或者等待操作,也变得更加灵活。

例子:

package 多线程;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//这个2个线程生产蛤,2个线程消费蛤,利用lock锁和Condition类就可以指定等待和幻想线程,形成生产一个消费一个的情况
class Data
{
    private String name;
    private int number=1;
    private boolean flag=false;
    private Lock l =new ReentrantLock();//Lock为抽象类,只能利用子类多态创建。
    private Condition Customer=l.newCondition();
    private Condition productor=l.newCondition();//此方法为创建一个Condition对象
    public void set(String name)throws InterruptedException
    {
        l.lock();//如果后面内容抛出异常,加锁也习惯性的放在try的外面。
        try 
        {
            while(flag)
            {
                productor.await();
            }
            this.name=name+"..."+this.number++;
            System.out.println(Thread.currentThread().getName()+"生产者"+this.name);
            flag=true;
            Customer.signal();
        } 
        finally
        {
            l.unlock();//注意无论发生什么最后必须解锁
        }
    }
    public void show()throws InterruptedException
    {    
        l.lock();
        try 
        {
            while(!flag)
            {
                Customer.await();
            }
            System.out.println(Thread.currentThread().getName()+"消费者"+this.name);
            flag=false;
            productor.signal();
        } 
        finally
        {
            l.unlock();
        }
    }    
}
class Productor implements Runnable
{
    private Data d;
    Productor(Data d)
    {
        this.d=d;
    }//利用这个写法可以保证几个线程都是用的同一个Data对象的资源。
    public void run()
    {
        while(true)
        {
            try
            {
                d.set("蛤");
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}
class Customer implements Runnable
{
    private Data d;
    Customer(Data d)
    {
        this.d=d;
    }
    public void run()
    {
        while(true)
        {
            try
            {
                d.show();
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}
public class LockTest 
{
    public  static void main(String[] args)
    {
        Data d=new Data();
        Productor pro = new Productor(d);
        Customer con = new Customer(d);
        Thread t1=new Thread(pro);
        Thread t2=new Thread(pro);
        Thread t3=new Thread(con);
        Thread t4=new Thread(con);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

 

输出结果
Thread-2消费者蛤...73454
Thread-0生产者蛤...73455
Thread-3消费者蛤...73455
Thread-1生产者蛤...73456
Thread-2消费者蛤...73456
Thread-0生产者蛤...73457
Thread-3消费者蛤...73457
Thread-1生产者蛤...73458
Thread-2消费者蛤...73458
Thread-0生产者蛤...73459
Thread-3消费者蛤...73459
一直下去,可以看出程序正确

4.lock类中提供了一种接口ReadWriteLock是一种特殊的锁,又叫读写锁,利用此锁划分读内容和写内容,读内容允许多个线程进入,写内容一次只允许一个线程进入,且写线程进入时,不允许读线程进入。

 

posted @ 2017-07-25 20:42  来的有点抖哟  阅读(173)  评论(0)    收藏  举报