余瑜的博客 余瑜的博客
首页
  • 并发
  • 线程池
  • spring
  • maven
  • 其他
  • redis
  • mysql
  • linux
  • zookeeper
  • docker
  • terminal
  • kong插件开发
  • 资料
  • leetCode-简单
  • blog
  • 其他
关于
GitHub (opens new window)
首页
  • 并发
  • 线程池
  • spring
  • maven
  • 其他
  • redis
  • mysql
  • linux
  • zookeeper
  • docker
  • terminal
  • kong插件开发
  • 资料
  • leetCode-简单
  • blog
  • 其他
关于
GitHub (opens new window)
  • 并发

    • JVM
    • Synchronized
    • volatile
    • CAS
    • AQS
    • ReentrantLock
    • Condition介绍及使用
      • 前言
      • 介绍
      • 简单的使用
        • Object.wait()
        • lock.newCondition()
      • 生产消费模式
        • Object.wait()
        • lock.newCondition()
      • 总结
    • Condition源码解析
    • jdk1.7-HashMap
    • jdk1.7-ConcurrentHashMap
  • 线程池

  • spring

  • maven

  • 其他

  • JAVA
  • 并发
余瑜
2020-02-03
目录

Condition介绍及使用

# 前言

Condition是用来替代传统的Object的wait()、notify()的,相比使用Object的wait()、notify()实现线程间协作更加安全和高效

# 介绍

  1. 生成一个Condition的代码是lock.newCondition()
  2. 调用Condition的await()和signal()方法,都必须在lock之内,就是说必须在lock.lock()和lock.unlock之间才可以使用
  3. Condition中的await()对应Object的wait()
  4. Condition中的signal()对应Object的notify()
  5. Condition中的signalAll()对应Object的notifyAll()

# 简单的使用

# Object.wait()

public class ConditionDemo1 {

   Object lock = new Object();

    public static void main(String[] args) {
        ConditionDemo1 demo = new ConditionDemo1();
        new Thread(() -> demo.test1()).start();
        new Thread(() -> demo.test2()).start();

    }

    void test1() {
        synchronized (lock){
            System.out.println("1号  上锁");
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("1号  收到信号不等了");
        }
        System.out.println("1号  完全释放锁");
    }
    
    void test2() {
        synchronized (lock){
            System.out.println("2号  上锁");
            lock.notifyAll();
            System.out.println("2号  叫醒1号");
        }
        System.out.println("2号  完全释放锁");
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

运行结果如下

  • 1号 上锁
  • 2号 上锁
  • 2号 叫醒1号
  • 2号 完全释放锁
  • 1号 收到信号不等了
  • 1号 完全释放锁

# lock.newCondition()

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

public class ConditionDemo2 {

    ReentrantLock lock;
    Condition condition;

    ConditionDemo2() {
        lock = new ReentrantLock();
        condition = lock.newCondition();
    }

    public static void main(String[] args) {
        ConditionDemo2 demo = new ConditionDemo2();
        new Thread(() -> demo.test1()).start();
        new Thread(() -> demo.test2()).start();
    }

    void test1() {
        try {
            lock.lock();
            System.out.println("1号  上锁");
            try {
                System.out.println("1号  等待");
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("1号  收到信号不等了");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            System.out.println("1号  释放锁");
        }
    }


    void test2() {
        try {
            lock.lock();
            System.out.println("2号  上锁");
            condition.signalAll();
            System.out.println("2号  叫醒1号");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            System.out.println("2号  释放锁");
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

运行结果如下

  • 1号 上锁
  • 1号 等待
  • 2号 上锁
  • 2号 叫醒1号
  • 2号 完全释放锁
  • 1号 收到信号不等了
  • 1号 释放锁

# 生产消费模式

# Object.wait()

import java.util.LinkedList;

/**
 * 生产消费 列队最大10
 */
public class ConditionDemo3 {


    volatile LinkedList<Integer> list = new LinkedList();
    static final int MAX_SIZE = 10;

    Object lock = new Object();

    public static void main(String[] args) {
        ConditionDemo3 demo = new ConditionDemo3();
        new Thread(() -> demo.test1(), "c1").start();
        new Thread(() -> demo.test1(), "c2").start();
        new Thread(() -> demo.test2(), "p1").start();
        new Thread(() -> demo.test2(), "p2").start();
    }

    void test1() {
        String name = Thread.currentThread().getName() + ":";
        synchronized (lock) {
            System.out.println(name + "上锁");

            for (int i = 0; i < 100; i++) {
                while (list.size() == MAX_SIZE) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(name + "等待");
                }
                list.add(i);
                lock.notifyAll();
            }
        }
        System.out.println(name + "释放锁");
    }

    void test2() {
        String name = Thread.currentThread().getName() + ":";
        synchronized (lock) {
            System.out.println(name + "上锁");
            while (true) {
                while (list.isEmpty()) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(name + "list为空-等待");
                }
                System.out.println(name + "消费" + list.removeFirst() + "\t" + "list容量为:" + (list.size() + 1));
                lock.notifyAll();
            }
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

# lock.newCondition()

package com.luban.self;

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

/**
 * 生产消费 列队最大10
 */
public class ConditionDemo4 {


    volatile LinkedList<Integer> list = new LinkedList();
    static final int MAX_SIZE = 10;

    ReentrantLock lock;
    Condition product;
    Condition customer;

    ConditionDemo4() {
        lock = new ReentrantLock();
        product = lock.newCondition();
        customer = lock.newCondition();
    }

    public static void main(String[] args) {
        ConditionDemo4 demo = new ConditionDemo4();
        new Thread(() -> demo.test1(), "c1").start();
        new Thread(() -> demo.test1(), "c2").start();
        new Thread(() -> demo.test2(), "p1").start();
        new Thread(() -> demo.test2(), "p2").start();
    }

    void test1() {
        String name = Thread.currentThread().getName() + ":";
        try {
            lock.lock();
            System.out.println(name + "上锁");

            for (int i = 0; i < 100; i++) {
                while (list.size() == MAX_SIZE) {
                    try {
                        product.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(name + "等待");
                }
                list.add(i);
                customer.signalAll();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            System.out.println(name + "释放锁");
        }
    }

    void test2() {
        String name = Thread.currentThread().getName() + ":";

        try {
            lock.lock();
            System.out.println(name + "上锁");
            while (true) {
                while (list.isEmpty()) {
                    try {
                        customer.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(name + "list为空-等待");
                }
                System.out.println(name + "消费" + list.removeFirst() + "\t" + "list容量为:" + (list.size() + 1));
                product.signalAll();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

# 总结

可以看到使用#newCondition方法时可以明确的指定具体将那种类型的锁取消等待, 在线程多的情况下可以起到很大的优化

上次更新: 2021/02/20, 19:26:07

← ReentrantLock Condition源码解析→

Theme by Vdoing | Copyright © 2018-2022 逆光世间 | 备案号: 京ICP备19016086号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式