`
yiding_he
  • 浏览: 449125 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

一个对象等待多个线程

阅读更多
wait 和 notify 方法可用于多个线程等待一个线程。有时候我们需要在主线程中发起多个线程,然后等待它们全部执行完再继续。最后面是一个简单例子。

如何判断这些线程是否都执行完毕,这里有一点讲究。如果靠主线程自己计数,就有可能在加一的过程中错过了某些 notify。所以需要由子线程完成的时候来给计数器加一。子线程之间是相互异步的,所以要用锁来同步这个动作。那么把计数器放在锁对象里面就是自然而然的事情了。

/**
 * 一个对象等待多个对象
 */
public class MultipleNotify {

    /**
     * 程序入口
     *
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        new MultipleNotify().go();
    }

    /**
     * 演示如何使用 wait() 和 notify() 实现一个对象等待多个对象
     */
    public void go() {
        // 锁对象中包含了一个数值
        final Lock lock = new Lock();

        // 运行 20 个线程
        Notifier[] notifiers = new Notifier[20];
        for (int i = 0; i < notifiers.length; i++) {
            notifiers[i] = new Notifier(lock);
            notifiers[i].start();
        }

        // 循环等待,通过 lock 的值来判断是否结束等待
        boolean enough = false;
        while (!enough) {
            try {
                synchronized (lock) {
                    lock.wait();
                    if (lock.value == notifiers.length) {
                        enough = true;
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("OK!");
    }

    /**
     * 执行的线程。主线程要等待所有 Notifier 执行完毕才会继续
     */
    private class Notifier extends Thread {

        private final Lock lock;

        private Notifier(Lock lock) {
            this.lock = lock;
        }

        public void run() {
            int sleep = 0;
            try {
                sleep = 500 + new Random().nextInt(2000);
                Thread.sleep(sleep);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 执行 lock.notify() 的同时将 lock 对象的值加 1
            synchronized (lock) {
                lock.setValue(lock.getValue() + 1);
                System.out.println("lock = " + lock.getValue() + ", sleep:" + sleep);
                lock.notify();
            }
        }
    }

    /**
     * 包含一个数值的锁
     */
    private class Lock {

        private int value = 0;

        public int getValue() {
            return value;
        }

        public void setValue(int value) {
            this.value = value;
        }
    }
}
分享到:
评论
1 楼 dongfei999 2008-08-12  
好贴正需要。

相关推荐

    使一个线程等待一个事件发生

    WaitForSingleObject用于等待单个事件,而WaitForMultipleObjects则可以同时等待多个事件。 3. 设置事件状态 当需要触发事件,让等待的线程继续执行时,可以调用SetEvent函数将事件设置为有信号状态。这将唤醒所有...

    C++ 等待线程结束

    当一个程序包含多个执行路径,即线程,有时我们需要确保某个线程执行完毕后再进行下一步操作,这就涉及到“等待线程结束”的功能。本篇文章将详细探讨如何在C++中实现这一功能。 首先,C++11引入了对线程支持的标准...

    WinForm C#多线程等待窗体

    在标题“WinForm C#多线程等待窗体”中,我们探讨的关键点是如何在进行耗时操作时创建一个等待窗体,让用户知道程序正在执行任务,并且不允许用户进行其他操作,直到任务完成。描述提到了“非托管资源”和...

    多线程事件对象通讯

    线程可以通过调用`WaitForSingleObject`或`WaitForMultipleObjects`来等待一个或多个事件对象。这些函数会让当前线程挂起,直到指定的事件对象变为信号状态。这在多线程环境中用于确保某些资源只被一个线程访问,...

    易语言 API线程等待

    线程是程序执行的最小单元,一个进程可以包含一个或多个线程。多线程是指在一个进程中同时运行多个线程,以提高程序的并发性和效率。然而,多线程编程中经常需要控制线程的执行顺序,确保某些线程完成特定任务后再...

    线程异步工作,当一个线程结束时异步通知另一线程

    `std::condition_variable`是一个同步原语,允许线程等待特定条件满足,而`std::atomic`则用于原子操作,保证数据在多线程环境中的一致性。 - 使用`std::condition_variable`,一个线程在完成任务后可以唤醒等待的...

    线程和内核对象的同步

    而自动重置事件在通知一个等待线程后自动恢复。事件对象可以用于同步开始或结束操作,或者作为信号机制。 4. **等待定时器内核对象**:等待定时器允许线程在一定时间后被唤醒,或者在被通知后立即唤醒。这对于实现...

    C#多线程等待窗体

    创建新线程的基本步骤包括定义一个方法作为新线程的入口点,然后实例化`Thread`对象并传入该方法。在等待窗体的应用中,这个新线程通常会执行耗时的操作,例如读取大文件、网络通信或者复杂的计算。 等待窗体的核心...

    c++ 面向对象多线程编程

    4. 线程局部存储:使用`std::thread_local`关键字,可以在每个线程中存储私有数据,即使在多个线程中使用同一函数,也不会互相干扰。 5. 线程池:线程池是一组预先创建的线程,当有新任务时,从池中分配线程而不是...

    面向对象的多线程编程

    - **线程同步**:为了防止多个线程同时访问共享资源导致的数据竞争问题,C++提供了多种同步机制,如互斥锁(`std::mutex`)、条件变量(`std::condition_variable`)等。 ##### 示例代码: ```cpp #include #...

    易语言多线程传递多参数

    多线程是指一个程序内可以同时执行多个独立的执行流,每个执行流被称为一个线程。在易语言中,我们可以通过创建线程对象来实现多线程。线程间可以并行或交替执行,提高了程序的响应速度和资源利用率。在处理大量数据...

    易语言线程互斥对象解决

    线程互斥对象允许我们限制对共享资源的访问,防止多个线程同时访问同一资源,从而避免数据竞争和不一致状态。 1. **线程互斥对象(Mutex)**: 线程互斥对象是一种同步机制,当一个线程获得了Mutex的所有权后,...

    多线程一个类对象一个日志

    多线程是指在一个程序中可以同时执行多个线程,每个线程都有自己的执行路径。在多线程编程中,可以实现任务并行化,提高程序的执行效率,尤其是在CPU密集型或I/O密集型的任务中。然而,多线程也带来了数据共享和同步...

    用VB6实现多线程

    线程是操作系统分配CPU时间的基本单位,一个进程可以包含一个或多个线程。在单线程程序中,所有操作都按顺序执行;而在多线程程序中,不同任务可以在不同的线程上并行运行。 要实现在VB6中创建线程,我们需要了解和...

    C#线程带一个及多个参数实例

    1. 线程安全:当多个线程访问同一资源时,可能会出现竞态条件。使用`lock`关键字或`Monitor`类可以帮助确保线程同步,防止数据不一致。 2. 资源管理:线程会占用系统资源,因此需要合理地创建和销毁线程。长时间运行...

    易语言判断多个线程运行结束

    - 压缩包中的"易语言判断多个线程运行结束源码"文件,应包含了一个示例程序,演示了如何创建并管理多个线程,以及如何判断这些线程是否已经结束。具体代码细节可能包括线程创建、线程状态查询、子程序设计等关键...

    java多线程的条件对象和锁对象demo

    在`MultiThreadTest0.1`这个示例中,可能包含了一个或多个人工创建的线程类,它们会使用`ReentrantLock`和`Condition`进行同步。通常,线程会在获取锁后检查一个条件,如果条件不满足,线程就会释放锁并等待。当条件...

    vc++ multithread多线程教程---线程通信--利用事件对象,线程同步--使用信号量,线程同步--使用互斥量,线程同步--使用临界区

    而自动重置事件在被一个线程唤醒后,会自动重置状态,只唤醒一个等待线程。 二、信号量 信号量是一种计数型同步机制,用于控制对共享资源的访问数量。它维护一个非负整数值,当值大于0时,线程可以获取一个信号量并...

    VB 多线程 多个参数传入

    2. **参数传递**: 要传递多个参数给新线程,可以使用`ParameterizedThreadStart`委托,它允许你传递一个对象数组作为参数。首先定义一个接受参数的方法,然后在创建线程时使用这个方法。 ```vb Private Sub ...

Global site tag (gtag.js) - Google Analytics