java基础知识回顾之java Thread类学习(把)--java.util.concurrent.locks(JDK1.5)与synchronized异同讲解

看API文档介绍几个方法:

 JDK1.5中提供了多线程的升级解决方案:

特点: 1.将同步synchronized显示的替换成Lock
                    2.接口Condition:Condition替代了Object监视器方法(wait、notify、notifyAll),分别替换成了await(),signal() (唤醒一个等待线                   程),signalAll() 唤醒多个线程。一个锁可以绑定多个condition对象,可以对应好几组wait,notify,notifyAll动作。

java.util.concurrent.locks接口
 *     Lock接口下面的方法
 *     void lock():获取锁,如果锁不可用,出于线程调度目的,将禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态。
 *     boolean tryLock():如果获得了锁,返回true。如果别的线程正在持有锁,返回false
 *     boolean tryLock(long time,//等待多长时间获得锁
                TimeUnit unit)
                throws InterruptedException:
       如果获取到锁,立即返回true,如果别的线程正在持有锁,会等待参数给定的时间,如果在这段时间内获得了锁就返回true,如果等待超时,返  回false。

locks的实现类:
      java.lang.Object
             -->java.util.concurrent.locks.ReentrantLock类一个可重入的互斥锁 Lock,替代synchronized,比synchronized有更强大的功能
             -->Java.util.concurrent.locks.ReadWriteLock 提供了一对可供读写并发的锁。

 使用新的锁完成生产者消费者模型:

代码如下:

仓库类(资源)

class ResourceNew{
    private String name;
    private boolean flag = false;
    private int count=1;

    private final Lock lock = new ReentrantLock();//将同步synchronized显示的替换成Lock
    private Condition condition_cusumer = lock.newCondition();//同一个锁上可以绑定多个相关的Condition
    private Condition conditon_producer = lock.newCondition();

    public  void set(String name) throws InterruptedException{
        try{
            lock.lock();//显示的
            while(flag){
                conditon_producer.await();//生产者等待t1,t2
            }
            this.name = name+"---"+count++;
            System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
            this.flag = true;
//condition.signalAll();//唤醒本方和唤醒对方
            condition_cusumer.signal();//唤醒某个消费者
        }finally{
            lock.unlock();//每个线程进入锁必须要执行的操作,最终要释放锁
        }
    }

    public  void out() throws InterruptedException{
        try{
            lock.lock();
            while(!flag){
                condition_cusumer.await();//消费者等待
            }
            System.out.println(Thread.currentThread().getName()+".消费者."+this.name);
            this.flag = false;
            conditon_producer.signalAll();//唤醒生产者
        }finally{
            lock.unlock();
        }
    }

}

生产者:

/**
 *
 * @author Administrator
 * 生产者负责生产,操作同一个资源,但是是生产动作
 *
 */
class producerNew implements Runnable{
    private ResourceNew res;
    public producerNew(ResourceNew res){
        this.res = res;
    }
    public void run() {
        while(true){
            try {
                res.set("..商品..");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
/**
 *
 * @author Administrator
 * 消费者负责消费生产者提供的产品,操作的同一个资源,但是是消费动作
 *
 */
class CusumerNew implements Runnable{
    private ResourceNew res;
    public CusumerNew(ResourceNew res){
        this.res = res;
    }
    public void run() {
        while(true){
            try {
                res.out();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

消费者:

/**
 *
 * @author Administrator
 * 消费者负责消费生产者提供的产品,操作的同一个资源,但是是消费动作
 *
 */
class CusumerNew implements Runnable{
    private ResourceNew res;
    public CusumerNew(ResourceNew res){
        this.res = res;
    }
    public void run() {
        while(true){
            try {
                res.out();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

 synchronized和java.util.concurrent.locks.Lock的异同 :
 * 相同点:Lock能完成synchronized所实现的所有功能。
 * 不同点:1.Lock比Synchonized更精确的线程锁语义和更好的性能。(Synchonized是独占锁,性能不高,而Lock是借助于JNI,性能更高)
 *            2.Lock必须手动释放锁,在finally里面调用unlock()方法释放锁,而synchronized会自动释放锁。

java基础知识回顾之java Thread类学习(把)--java.util.concurrent.locks(JDK1.5)与synchronized异同讲解

时间: 2024-10-12 19:38:25

java基础知识回顾之java Thread类学习(把)--java.util.concurrent.locks(JDK1.5)与synchronized异同讲解的相关文章

Java基础知识回顾-18(Math类,Arrays类和大数据运算)

public class MathDemo { public static void main(String[] args) { double x=12.2; //取绝对值 System.out.println(Math.abs(-99)); //向上取整 System.out.println(Math.ceil(x)); //向下取整 System.out.println(Math.floor(x)); //取最大值 System.out.println(Math.max(2,5)); //取

java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

 *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时候才能消费,仓空则等待. *3.当消费者发现仓储没有产品可消费的时候,会唤醒等待生产者生产. *4.生产者在生产出可以消费的产品的时候,应该通知等待的消费者去消费. 下面先介绍个简单的生产者消费者例子:本例只适用于两个线程,一个线程生产,一个线程负责消费. 生产一个资源,就得消费一个资源. 代码如下: pub

java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)

1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以可以被任意对象调用的方法,定义在Object基类中. wait()方法:对此对象调用wait方法导致本线程放弃对象锁,让线程处于冻结状态,进入等待线程的线程池当中.wait是指已经进入同步锁的线程,让自己暂时让出同步锁,以便使其他正在等待此锁的线程可以进入同步锁并运行,只有其它线程调用notify方

java基础知识回顾之java Thread类学习(六)--java多线程同步函数用的锁

1.验证同步函数使用的锁----普通方法使用的锁 思路:创建两个线程,同时操作同一个资源,还是用卖票的例子来验证.创建好两个线程t1,t2,t1线程走同步代码块操作tickets,t2,线程走同步函数封装的代码操作tickets,同步代码块中的锁我们可以指定.假设我们事先不知道同步函数用的是什么锁:如果在同步代码块中指定的某个锁(测试)和同步函数用的锁相同,就不会出现线程安全问题,如果锁不相同,就会发生线程安全问题. 看下面的代码:t1线程用的同步锁是obj,t2线程在操作同步函数的资源,假设不

java基础知识回顾之java Thread类学习(五)--java多线程安全问题(锁)同步的前提

这里举个例子讲解,同步synchronized在什么地方加,以及同步的前提: * 1.必须要有两个以上的线程,才需要同步. * 2.必须是多个线程使用同一个锁. * 3.必须保证同步中只能有一个线程在运行,锁加在哪一块代码 那么我们要思考的地方有:1.知道我们写的哪些是多线程代码 2.明确共享数据 3.明确多线程运行的代码中哪些语句是操作共享数据的.. 4.要确保使用同一个锁. 下面的代码:需求:两个存户分别往银行存钱,每次村100块,分三次存完. class bank{ private int

java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)

上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // TODO Auto-generated method stub while(true){ if(ticket > 0){//当线程0被调起的时候,当执行到这条判断语句的时候,线程1被调起抢了CPU资源,线程0进入冻结状态. try { Thread.sleep(100);//中断当前活跃的线程,或者

java基础知识回顾之java Thread类学习(七)--java多线程安全问题(死锁)

死锁:是两个或者两个以上的线程被无限的阻塞,线程之间互相等待所需资源. 线程死锁产生的条件: 当两个线程相互调用Join()方法. 当两个线程使用嵌套的同步代码块的时候,一个线程占用了另一个线程的锁,互相等待阻塞,就有可能产生死锁. 下面看代码: 代码1:死锁的案例 package com.lp.ecjtu.Thread; /* 死锁:常见情景之一:同步的嵌套. */ class Ticket implements Runnable { private int num = 100; Object

java基础知识回顾之java Thread类学习(九)--wait和notify区别

wait和sleep区别:  相同点:调用wait,sleep方法都可以是线程进入阻塞状态,让出cpu的执行权. 不同点:1.sleep必须指定时间,但是wait方法可以指定时间,也可以不指定时间. 2.wait方法必须在同步中使用,但是sleep不一定在同步中使用. 3.在同步中,调用sleep方法释放CPU执行权,但是不会释放锁,即使让出了CPU执行权,其它线程也无法进入同步锁,不能得到执行.但是wait  方法不仅释放CPU执行权,而且释放同步锁,进入阻塞状态.也就是说其它等待此锁的线程可

java基础知识回顾之java Thread类学习(三)--java线程实现常见的两种方式实现好处:

总结:实现Runnable接口比继承Thread类更有优势: 1.因为java只能单继承,实现Runnable接口可以避免单继承的局限性 2.继承Thread类,多个线程不能处理或者共享同一个资源,但是实现Runnable接口可以处理同一个资源. 下面我们做个测试:验证下.车站的售票系统售票的例子,车站的各个售票口相当于各个线程,我们先使用第一种方法几继承Thread类的方式实现: 代码如下: package com.lp.ecjtu.Thread; /** * * @author Admini