Lock&Condition实现线程同步通信

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

public class ConditionCommunication {
    final Business business = new Business();

    public static void main(String[] args) {
        new ConditionCommunication().init();
    }

    private void init() {

        new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i <= 50; i++) {
                    business.sub(i);
                }
            }
        }).start();

        for (int i = 0; i <= 50; i++) {
            business.main(i);
        }

    }

    class Business {
        private boolean bShouldSub = true;
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();

        public void sub(int i) {
            lock.lock();
            try {
                while (!bShouldSub) {
                    condition.await();
                }

                for (int j = 1; j <= 10; j++) {

                    System.out.println("sub thread sequence of" + j
                            + ",loop of " + i);
                }
                bShouldSub = false;
                condition.signal();
            } catch (Exception e) {

                e.printStackTrace();

            } finally {
                lock.unlock();
            }
        }

        public synchronized void main(int i) {
            lock.lock();
            try {
                while (bShouldSub) {
                    condition.await();
                }

                for (int j = 1; j <= 20; j++) {

                    System.out.println("main thread sequence of" + j
                            + ",loop of " + i);
                }
                bShouldSub = true;
                condition.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

    }

}

阻塞队列实现

两个condition实现只唤醒对方

作为一个示例,假定有一个绑定的缓冲区,它支持 put 和 take 方法。如果试图在空的缓冲区上执行 
take 操作,则在某一个项变得可用之前,线程将一直阻塞;如果试图在满的缓冲区上执行 put 操作,则在有空间变得可用之前,线程将一直阻塞。我们喜欢在单独的等待 set 中保存 put 线程和 take 线程,这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,一次只通知一个线程。可以使用两个 Condition 实例来做到这一点。
 class BoundedBuffer {   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {     lock.lock();
     try {
       while (count == items.length) 
         notFull.await();
       items[putptr] = x; 
       if (++putptr == items.length) putptr = 0;
       ++count;       notEmpty.signal();
     } finally {
       lock.unlock();
     }
   }

   public Object take() throws InterruptedException {     lock.lock();
     try {
       while (count == 0) 
         notEmpty.await();
       Object x = items[takeptr]; 
       if (++takeptr == items.length) takeptr = 0;
       --count;       notFull.signal();
       return x;     } finally {
       lock.unlock();
     }
   } 
 }

ArrayBlockingQueue 类提供了这项功能,因此没有理由去实现这个示例类。)

三个条件多路通信  老大通知老二,老二通知老三,老三通知老大

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

public class ThreeThreadConditionCommunication {
    final Business business = new Business();

    public static void main(String[] args) {
        new ThreeThreadConditionCommunication().init();
    }

    private void init() {

        new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i <= 50; i++) {
                    business.sub2(i);
                }
            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i <= 50; i++) {
                    business.sub3(i);
                }
            }
        }).start();
        
        for (int i = 0; i <= 50; i++) {
            business.main(i);
        }

    }

    class Business {
        private int flag = 1;
        Lock lock = new ReentrantLock();
        Condition condition1 = lock.newCondition();
        Condition condition2= lock.newCondition();
        Condition condition3= lock.newCondition();
        public void sub2(int i) {
            lock.lock();
            try {
                while (flag!=2) {
                    condition2.await();
                }

                for (int j = 1; j <= 10; j++) {

                    System.out.println("sub2 thread sequence of" + j
                            + ",loop of " + i);
                }
                flag = 3;
                condition3.signal();
            } catch (Exception e) {

                e.printStackTrace();

            } finally {
                lock.unlock();
            }
        }

        public void sub3(int i) {
            lock.lock();
            try {
                while (flag!=3) {
                    condition3.await();
                }

                for (int j = 1; j <= 10; j++) {

                    System.out.println("sub3 thread sequence of" + j
                            + ",loop of " + i);
                }
                flag =1;
                condition1.signal();
            } catch (Exception e) {

                e.printStackTrace();

            } finally {
                lock.unlock();
            }
        }
        
        public synchronized void main(int i) {
            lock.lock();
            try {
                while (flag!=1) {
                    condition1.await();
                }

                for (int j = 1; j <= 20; j++) {

                    System.out.println("main thread sequence of" + j
                            + ",loop of " + i);
                }
                flag = 2;
                condition2.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

    }

}

Lock&Condition实现线程同步通信

时间: 2024-10-22 23:43:54

Lock&Condition实现线程同步通信的相关文章

Lock&amp;Condition实现线程同步通信

一,Lock Lock比传统的线程模型中的synchronized方式更加面向对象,因为"锁"本身就是一个对象. 两个线程执行的代码要实现同步互斥的效果,他们必须用同一个Lock对象. 读写锁:(1)读锁:多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,我们只需要代码中用对相应的锁即可.如果只读数据,那么可以很多人(线程)同时读,但是不能同时写,此时就加读锁.如果代码需要修改数据,此时只能一个人(一个线程)写,此时不能同时读,那么就加写锁. 总之,读时,上读锁:写时,上写锁.

线程间通信 Object/wait(),notify() 和 Lock/Condition/await(),signal()

基本前提知识: 一:Object/wait(), notify(), notifyAll() 1:wait() 方法暂停当前线程,并立即释放对象锁; 2:notify()/notifyAll() 方法唤醒其他等待该对象锁的线程,并在执行完同步代码块中的后续步骤后,释放对象锁 3:notify()和notifyAll()的区别在于: notify只会唤醒其中一个线程, notifyAll则会唤醒全部线程. 至于notify会唤醒哪个线程,是由线程调度器决定的. 例子: public class T

Java多线程——Lock&amp;Condition

Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象. package java_thread; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockTest { /** * @param args */ pu

Lock+Condition 相对于 wait+notify 的一个优势案例分析

问题的描述 启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5, 然后是线程2打印6,7,8,9,10, 然后是线程3打印11,12,13,14,15. 接着再由线程1打印16,17,18,19,20....以此类推, 直到打印到45. wait+notify实现: package com.tonyluis; public class NumberPrintDemo { static int n = 1; static int state = 0; public static void

Condition实现线程通信

当线程在系统中运行时,线程的调度具有一定的透明性,通常程序无法准确控制线程的轮换执行,如果有需要,Python 可通过线程通信来保证线程协调运行. 假设系统中有两个线程,这两个线程分别代表存款者和取钱者,现在假设系统有一种特殊的要求,即要求存款者和取钱者不断地重复存款.取钱的动作,而且要求每当存款者将钱存入指定账户后,取钱者就立即取出该笔钱.不允许存款者连续两次存钱,也不允许取钱者连续两次取钱. 为了实现这种功能,可以借助于 Condition 对象来保持协调.使用 Condition 可以让那

Lock+Condition实现机制

前言:大部分多线程同步场景,在功能和性能层面,synchronized可以满足,少部分场景Lock可以满足,dubbo的源码也符合这个比例,需要使用到Condition的场景极少,整个dubbo源码中只在启动函数中,服务关闭这一处使用到了Lock+Condition机制. 1.Lock+Condition用法 生产者,消费者模式在面试coding中出场率很高,可以用synchronized+wait+ notify来实现,也可以使用Lock+Condition实现.直接上代码 public cl

Lock锁_线程_线程域

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms; namespace Lock锁_线程_线程

使用Lock锁实现线程同步

Lock锁:对需要上锁的地方上锁1) JDK1.5后新增的功能2)与Synchronized相比,Lock 可提供多种锁方案,更灵活3) Java.util.concurrent.lock 中的Lock是一个接口,它的实现类是一个Java类,而不是作为语言的特性(关键字)来实现注意:如果同步代码有异常,要将unLock0放到finally 中 使用步骤1)创建Lock对象2)调用lock0方法上锁3)调用unlock0方法解锁 Lock与synchronized的区别1) Lock是显示锁(手动

线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯

1.Lock相关知识介绍 好比我同时种了几块地的麦子,然后就等待收割.收割时,则是哪块先熟了,先收割哪块. 下面举一个面试题的例子来引出Lock缓存读写锁的案例,一个load()和get()方法返回值为空时的情况:load()的返回值是一个代理对象,而get()却是一个实实在在的对象:所以当返回对象为空是,get()返回null,load()返回一个异常对象:具体分析如下: 一个读写锁的缓存库案例:用上面那道面试题分析则很好理解: 线程阻塞问题:运用多个Condition对象解决 2. Lock