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 busine
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();
            }
        }

    }

}


本文出自 “点滴积累” 博客,请务必保留此出处http://tianxingzhe.blog.51cto.com/3390077/1716805

目录
相关文章
|
2月前
|
Java 调度
[Java]线程生命周期与线程通信
本文详细探讨了线程生命周期与线程通信。文章首先分析了线程的五个基本状态及其转换过程,结合JDK1.8版本的特点进行了深入讲解。接着,通过多个实例介绍了线程通信的几种实现方式,包括使用`volatile`关键字、`Object`类的`wait()`和`notify()`方法、`CountDownLatch`、`ReentrantLock`结合`Condition`以及`LockSupport`等工具。全文旨在帮助读者理解线程管理的核心概念和技术细节。
41 1
[Java]线程生命周期与线程通信
|
1月前
|
Java
JAVA多线程通信:为何wait()与notify()如此重要?
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是实现线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件满足时被唤醒,从而确保数据一致性和同步。相比其他通信方式,如忙等待,这些方法更高效灵活。 示例代码展示了如何在生产者-消费者模型中使用这些方法实现线程间的协调和同步。
38 3
|
1月前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
45 4
|
2月前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
24 1
|
2月前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
47 1
|
2月前
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
29 1
|
2月前
|
Java
|
2月前
|
Java 开发者
在 Java 多线程编程中,Lock 接口正逐渐取代传统的 `synchronized` 关键字,成为高手们的首选
【10月更文挑战第6天】在 Java 多线程编程中,Lock 接口正逐渐取代传统的 `synchronized` 关键字,成为高手们的首选。相比 `synchronized`,Lock 提供了更灵活强大的线程同步机制,包括可中断等待、超时等待、重入锁及读写锁等高级特性,极大提升了多线程应用的性能和可靠性。通过示例对比,可以看出 Lock 接口通过 `lock()` 和 `unlock()` 明确管理锁的获取和释放,避免死锁风险,并支持公平锁选择和条件变量,使其在高并发场景下更具优势。掌握 Lock 接口将助力开发者构建更高效、可靠的多线程应用。
26 2
|
3月前
|
Java
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
39 7
|
2月前
多线程通信和同步的方式有哪些?
【10月更文挑战第6天】
110 0