05月19, 2017

Java多线程Lock

JDK5以后为代码的同步提供了更加灵活的Lock+Condition模式,并且一个Lock可以绑定多个Condition对象

1.把原来的使用synchronized修饰或者封装的代码块用lock.lock()与lock.unlock()进行手动的锁获取与释放

//原来的同步方式
synchronized (obj) {
    ...
}

//JDK5.0新增的同步方式
//lock.unlock();建议最好要放在finally 执行
try {
    lock.lock();
    ...
} finally {
    lock.unlock();
}

2.把原来线程之间的通讯方式由锁对线obj.wait()和obj.notify()改成了Condition对象的con.await()与con.signal()方法

如下用Lock的方式重写多生产者多消费者模式时,线程可以指定唤醒生产者或者消费者,这样拥有更高的效率与安全性

package jdk5lockDome;

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

/**
 * @author wpy
 * 
 */
public class ProducerConsumer {
    public static void main(String[] args) {
        Resource resource = new Resource();

        Producer producer0 = new Producer(resource);
        Producer producer1 = new Producer(resource);

        Consumer consumer2 = new Consumer(resource);
        Consumer consumer3 = new Consumer(resource);

        Thread t0 = new Thread(producer0);
        Thread t1 = new Thread(producer1);
        Thread t2 = new Thread(consumer2);
        Thread t3 = new Thread(consumer3);

        t0.start();
        t1.start();

        t2.start();
        t3.start();

    }

}

class Producer implements Runnable {
    private Resource resource;

    public Producer(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        while (true) {
            resource.set("资源");
        }
    }
}

class Consumer implements Runnable {
    private Resource resource;

    public Consumer(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        while (true) {
            resource.out();
        }
    }
}

class Resource {
    private String name;
    private int count = 1;
    // 是否生成完毕
    private boolean flag = false;

    /**
     * 互斥锁(同时只有一个线程拥有锁)
     */
    private Lock lock = new ReentrantLock();
    private Condition producerCon = lock.newCondition();
    private Condition consumerCon = lock.newCondition();

    /**
     * 生产方法
     * 
     * @param name
     */
    public void set(String name) {
        try {
            lock.lock();
            String threadName = Thread.currentThread().getName();
            while (flag) {
                System.out.println(threadName + "进入等待状态");
                producerCon.await();
            }
            System.out.println(threadName + "取得执行权");

            this.name = name + count;
            count++;
            System.out.println("生产者:" + this.name);
            flag = true;
            consumerCon.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 消费方法
     */
    public void out() {
        try {
            lock.lock();
            String threadName = Thread.currentThread().getName();
            while (!flag) {
                System.out.println(threadName + "进入等待状态");
                consumerCon.await();
            }
            System.out.println(threadName + "取得执行权");

            System.out.println("============消费者:" + name);
            flag = false;
            producerCon.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

  

  

本文链接:https://www.qiangshuidiyu.xin/post/2017-05-19.html

-- EOF --

Comments