Lock接口与等待唤醒机制

一  Lock接口

Lock接口中常用的方法:

我们使用Lock接口,以及其中的lock()方法和unlock()方法替代同步,对电影院卖票案例中Ticket类进行如下代码修改:

package com.oracle.demo01;

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

public class Myticket4 implements Runnable {
    private int ticket=100;
    //创建Lock接口实现类对象
    private Lock lock=new ReentrantLock();
    public void run() {
        while(true){
            //获取锁
            lock.lock();
            if(ticket>0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"出售第"+ticket--+"张票");
            }
            //释放锁
            lock.unlock();
        }
    }
    
}

二  等待唤醒机制

在开始讲解等待唤醒机制之前,有必要搞清一个概念——线程之间的通信:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同。通过一定的手段使各个线程能有效的利用资源。而这种手段即—— 等待唤醒机制。

等待唤醒机制所涉及到的方法:

 wait() :等待,将正在执行的线程释放其执行资格 和 执行权,并存储到线程池中。

  notify():唤醒,唤醒线程池中被wait()的线程,一次唤醒一个,而且是任意的。

  notifyAll(): 唤醒全部:可以将线程池中的所有wait() 线程都唤醒。

模拟资源类:

package com.oracle.demo03;

public class Resource {
    //共享资源
    public String name;
    public int age;
    //添加标记:true,赋值完成,false,输出完成
    public boolean flag=false;//先赋值在输出
}

输入线程类:

public class Input implements Runnable {
    //对Resource进行赋值
    private Resource r;
    public Input(){}
    public Input(Resource r){
        this.r=r;
    }
    public void run() {
        int i=0;
        while(true){
            //添加同步代码块
            synchronized (r) {
                //判断标记
                if(r.flag){
                    try {
                        r.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(i%2==0){
                    r.name="张三";
                    r.age=18;
                }else{
                    r.name="李四";
                    r.age=81;
                }
                r.flag=true;
                r.notify();
            }    
            i++;
        }
    }

}

输出线程类:

public class Output implements Runnable {
    private Resource r;
    public Output(){}
    public Output(Resource r){
        this.r=r;
    }
    public void run() {
        
        //对Resource进行输出
        while(true){
        
            //添加同步锁
            synchronized (r) {
                //判断标记
                if(!r.flag){
                    try {
                        r.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(r.name+"..."+r.age);
                //改标记,唤醒input
                r.flag=false;
                r.notify();
            }
        
        }
    }
    
}

测试类:

public class Demo01 {
    public static void main(String[] args) {
        Resource r=new Resource();
        //创建线程任务
        Input in=new Input(r);
        Output out=new Output(r);
        Thread tin=new Thread(in);
        Thread tout=new Thread(out);
        tin.start();
        tout.start();
    }
}

运行结果:

 

 

 

posted @ 2019-01-10 11:03  张宗强1  阅读(218)  评论(0编辑  收藏  举报