多线程学习

来源:互联网 发布:四维彩超数据正常值 编辑:程序博客网 时间:2024/06/14 04:35
public class TestProductorAndConsumerForLock {public static void main(String[] args) {Clerk2 clerk = new Clerk2();Productor2 pro = new Productor2(clerk);Consumer2 con = new Consumer2(clerk);new Thread(pro, "生产者 A").start();new Thread(con, "消费者 B").start(); new Thread(pro, "生产者 C").start(); new Thread(con, "消费者 D").start();}}class Clerk2 {private int product = 0;private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();// 进货public void get() {lock.lock();try {while (product >= 1) { // 为了避免虚假唤醒,应该总是使用在循环中。System.out.println("产品已满!");try {condition.await();} catch (InterruptedException e) {}}System.out.println(Thread.currentThread().getName() + " : "+ ++product);condition.signalAll();} finally {lock.unlock();}}// 卖货public void sale() {lock.lock();try {while(product <= 0) {System.out.println("缺货!");try {condition.await();} catch (InterruptedException e) {}}System.out.println(Thread.currentThread().getName() + " : "+ --product);condition.signalAll();} finally {lock.unlock();}}}// 生产者class Productor2 implements Runnable {private Clerk2 clerk;public Productor2(Clerk2 clerk) {this.clerk = clerk;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}clerk.get();}}}// 消费者class Consumer2 implements Runnable {private Clerk2 clerk;public Consumer2(Clerk2 clerk) {this.clerk = clerk;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {clerk.sale();}}}

1.当多个线程(这里是4个线程)操作共享数据时,需要加锁,本例使用的是java.util.concurrent.locks.Lock

2.Lock相较于synchronized更加灵活,但是Lock必须在finally中解锁

3.Lock的await(), signalAll(),signal();分别对应老线程的await(),notifyAll(),notify()

4.若多个相同线程同时操作数据,存在唤醒,所以在循环中进行处理await操作,

如果将while改为if的话,两个线程同时抢占到cpu资源的话,执行到sale()方法时,--product就会被执行两次 ,就会出现错误,也就是虚假唤醒

注:有错之处,请大神指教

原创粉丝点击