您好,登录后才能下订单哦!
今天就跟大家聊聊有关如何使用wait() 和notify() 机制来完成睡眠和踢,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
使用 wait() 和 notify() 机制来完成“睡眠”和“踢”。实际的消费者工作由 OnConsume(Object) 方法处理,如清单 3 所示:
清单 3. 唤醒和通知 Consumer
/**
* Add an object to the Consumer.
* This is the entry point for the producer.
* After the item is added, the Consumer´s thread
* will be notified.
*
* @param the object to be ´consumed´ by this consumer
*/
public void add(Object o)
{
_queue.add(o);
kickThread();
}
/**
* Wake up the thread (without adding new stuff to consume)
*
*/
public void kickThread()
{
if (!this._thread.isInterrupted())
{
synchronized(_waitForJobsMonitor)
{
_waitForJobsMonitor.notify();
}
}
}
示例:MessagesProcessor
为了向您展示 Consumer 类是如何工作的,我们将使用一个简单示例。MessagesProcessor 类以异步方式处理进入的消息(也就是说,不干扰调用线程)。其工作是在每个消息到来时打印它。MessagesProcessor 具有一个处理到来的消息作业的内部 Consumer。当新作业进入空队列时,Consumer 调用 processMessage(String) 方法来处理它,如清单 4 所示:
清单 4. MessagesProcessor 类
class MessagesProcessor
{
String _name;
// anonymous inner class that supplies the consumer
// capabilities for the MessagesProcessor
private Consumer _consumer = new Consumer()
{
// that method is called on each event retrieved
protected void onConsume(Object o)
{
if (!(o instanceof String))
{
System.out.println("illegal use, ignoring");
return;
}
MessagesProcesser.this.processMessage((String)o);
}
}.setName("MessagesProcessor").init();
public void gotMessageEvent(String s)
{
_consumer.add(s);
}
private void processMessage(String s)
{
System.out.println(_name+" processed message: "+s);
}
private void terminate()
{
_consumer.terminateWait();
_name = null;
}
MessagesProcessor()
{
_name = "Example Consumer";
}
}
正如您可以从上面的代码中所看到的,定制 Consumer 相当简单。我们使用了一个匿名内部类来继承 Consumer 类,并重载抽象方法 onConsume()。因此,在我们的示例中,只需调用 processMessage。
Consumer 类的高级特性
除了开始时提出的基本需求以外,我们还为 Consumer 类提供了一些我们觉得有用的高级特性。
事件通知
onThreadTerminate():只在终止 Consumer 前调用该方法。我们出于调试目的覆盖了这个方法。
goingToRest():只在 Consumer 线程进入休眠前调用该方法(也就是说,只在调用 _waitForJobsMonitor.wait() 之前调用)。只在需要消费者在进入休眠之前处理一批已处理工作的复杂情况中,可能需要这种通知。
终止
terminate():Consumer 线程的异步终止。
terminateWait():设置调用线程一直等待,直到消费者线程实际终止为止。
在我们的示例中,如果使用 terminate() 而不是 terminateWait(),那么将会出现问题,因为在将 _name 设置成空值之后调用 onConsume() 方法。这将导致执行 processMessage 的线程抛出一个 NullPointerException。
结束语:Consumer 类的好处
可在参考资料一节下载 Consumer 类的源代码。请自由使用源代码,并按照您的需要扩展它。我们发现将这个类用于多线程应用程序开发有许多好处:
代码重用/重复代码的消除:如果您有 Consumer 类,就不必为您应用程序中的每个实例编写一个新的消费者。如果在应用程序开发中频繁使用生产者-消费者方案,这可以很大程度地节省时间。另外,请牢记重复代码是滋生错误的沃土。它还使基本代码的维护更为困难。
更少错误:使用验证过的代码是一种防止错误的好实践,尤其是处理多线程应用程序时。因为 Consumer 类已经被调试过,所以它更安全。消费者还通过在线程和资源之间担任安全中介来防止与线程相关的错误。消费者可以代表其它线程以顺序的方式访问资源。
漂亮、清晰的代码:使用 Consumer 类有助于我们编写出更简单的代码,这样的代码更容易理解和维护。如果我们不使用 Consumer 类,就必须编写代码来处理两种不同的功能:消费逻辑(队列和线程管理、同步等)和指定消费者的用法或功能的代码。
看完上述内容,你们对如何使用wait() 和notify() 机制来完成睡眠和踢有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。