首页 > 其他 > 详细

JUC 相关

时间:2020-12-09 10:00:56      阅读:26      评论:0      收藏:0      [点我收藏+]

同步监视器

  • condition同步监视器
  • condition类方法await\signalAll可替换Object方法wait,notify
/**
 *
 *  线程A执行+1操作,线程B执行-1操作。。。
 *
 A execute add ,num = 1
 D execute sub ,num = 0
 A execute add ,num = 1
 D execute sub ,num = 0
 A execute add ,num = 1
 D execute sub ,num = 0
 A execute add ,num = 1
 *
 *
 */
public class ConditionDemo {
    public static void main(String[] args) {
        Data data = new Data();

        new Thread(() ->{
            try {
                for (int i = 0; i < 10; i++) {
                    data.add();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();

        new Thread(() ->{
            try {
                for (int i = 0; i < 10; i++) {
                    data.sub();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "B").start();

        new Thread(() ->{
            try {
                for (int i = 0; i < 10; i++) {
                    data.add();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"C").start();

        new Thread(() ->{
            try {
                for (int i = 0; i < 10; i++) {
                    data.sub();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"D").start();
    }
}

class Data {
    private int num = 0;

    private ReentrantLock lock = new ReentrantLock();

    private Condition condition = lock.newCondition();

    //+1
    public void add() throws InterruptedException {
        lock.lock();
        try {
            // 使用while防止虚唤醒
            while (num != 0) {
                condition.await(); // 等待
            }
            System.out.println(Thread.currentThread().getName()+" execute add ,num = " + (++num));
            condition.signalAll();  // 唤醒全部线程
        } finally {
            lock.unlock();
        }

    }

    //-1
    public void sub() throws InterruptedException {
        lock.lock();
        try {
            // 使用while防止虚唤醒
            while (num == 0) {
                condition.await(); // 等待
            }
            System.out.println(Thread.currentThread().getName()+" execute sub ,num = " + (--num));
            condition.signalAll(); // 唤醒所有线程
        } finally {
            lock.unlock();
        }
    }
}

精准唤醒

  • 为每个线程添加Condition监视器
  • 使用Condition.single方法唤醒指定线程
package com.thread.juc;

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

/**
 * 
 *  实现多个线程顺序执行,Condition.single 唤醒指定线程
 *
     A :: exec..
     B :: exec..
     C :: exec..
     A :: exec..
     B :: exec..
     C :: exec..
     A :: exec..
 * 
 */
public class Sequence {
    public static void main(String[] args) {
        Executer executer = new Executer();


        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                executer.ExecA();
            }
        },"A").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                executer.ExecB();
            }

        },"B").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                executer.ExecC();
            }

        },"C").start();
    }
}

class Executer{
    // 标记位,确定当前线程和下一个线程
    private int flag = 1;

    // 使用同一个锁对象
    private ReentrantLock lock = new ReentrantLock();

    // 为每个线程添加监视器
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    public void ExecA() {
        lock.lock();
        try {
            while (1 != flag) {
                condition1.await();
            }
            flag = 2;
            System.out.println(Thread.currentThread().getName()+" :: exec..");
            condition2.signal(); // 唤醒指定线程
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void ExecB() {
        lock.lock();
        try {
            while (2 != flag) {
                condition2.await();
            }
            flag = 3;
            System.out.println(Thread.currentThread().getName()+" :: exec..");
            condition3.signal(); // 唤醒指定线程
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void ExecC() {
        lock.lock();
        try {
            while (3 != flag) {
                condition3.await();
            }
            flag = 1;
            System.out.println(Thread.currentThread().getName()+" :: exec..");
            condition1.signal(); // 唤醒指定线程
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

JUC 相关

原文:https://www.cnblogs.com/xiongyungang/p/14095040.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!