在我们获得触发之前,没有任何建议的副本在SO上回答了我的问题。
尝试这样做:我有一个观察者模式。当我想发送Events
时,我希望在Java thread中发送。
我需要将一个Object传递给线程,即Event
。
public class EventBus implements Runnable
{
private Thread t1;
public EventBus()
{
t1 = new Thread(this);
}
public void notify(Event event)
{
t1.start();
}
@Override
public void run()
{
for(Listener l : list)
l.handle(event);
}
}
那么如何在不使用类似这样的东西的情况下将我的Event对象传递给run()
?
Runnable r = new EventBus(param_value);
new Thread(r).start();
我知道将参数传递给Thread的方法是将它们放在Thread构造函数中,我不希望这样,我在How can I pass a parameter to a Java Thread?了解到了这一点。
每次调用Event
时,我都需要将新的notify()
传递给线程。在执行程序期间notify()
将被多次调用,它将携带不同的事件实例。
答案 0 :(得分:3)
我整理了一个简单的例子,其中sorta显示了我最近如何做异步事件发布。检查一下,我认为它非常自我解释:
主要方法:
public static void main(String[] args) throws InterruptedException {
Observer obs = new Observer();
EventBus.subscribe(obs, SomeEventImp.class);
SomeEventImp evt = new SomeEventImp(new Object(), "This is the value");
EventBus.publishAsync(evt);
Thread.sleep(Long.MAX_VALUE);
}
观察者界面:
public interface IObserver {
public void update(AEvent event);
}
观察员实施:
public class Observer implements IObserver {
@Override
public void update(AEvent event) {
System.out.println("I got and event from " + event.getSource() + " with a value of " + event.getValue());
}
}
AEvent课程:
public abstract class AEvent<T> {
protected final T value;
protected final Object source;
public AEvent(Object source, T value) {
this.value = value;
this.source = source;
}
public Object getSource() {
return source;
}
public T getValue() {
return value;
}
}
活动巴士:
public class EventBus {
// our observers
private static HashMap<IObserver, Class<?>> m_Observers = new HashMap<IObserver, Class<?>>();
// our incoming events
private static BlockingQueue<AEvent<?>> incoming = new LinkedBlockingQueue<AEvent<?>>();
// start our internal thread
static {
new Thread(new DelegationThread()).start();
}
// subscribe an observer
public static void subscribe(IObserver obs, Class<?> evtClass) {
synchronized (m_Observers) {
m_Observers.put(obs, evtClass);
}
}
// publish and event
public static void publishAsync(AEvent<?> event) {
incoming.add(event);
}
private static class DelegationThread implements Runnable {
@Override
public void run() {
while (true) {
try {
AEvent<?> evnt = incoming.take();
synchronized (m_Observers) {
for (Entry<IObserver, Class<?>> entry : m_Observers.entrySet()) {
if (entry.getValue() == evnt.getClass()) {
entry.getKey().update(evnt);
}
}
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
最后是事件实现:
public class SomeEventImp extends AEvent<String> {
public SomeEventImp(Object source, String value) {
super(source, value);
}
}
继续输出:
I got and event from java.lang.Object@5e1387c6 with a value of This is the value
显然你会想要清理一下......我只是在几分钟内将它打成一片,并没有真正检查这一切。
答案 1 :(得分:0)
显然你不能使用构造函数参数,因为你不想每次在你想要的计算上启动一个线程时调用构造函数。因此,线程的启动必须与它应该完成的工作区别开来。它必须开始,然后等到计算准备就绪,获取一个对象,告诉它要做什么,然后开始工作。
由于您似乎担心创建新线程,我会假设您需要一个执行一次计算的线程对象,然后让自己准备好另一个,等待它,然后重新开始。我没有看到无限循环的错误。
可能会对上述实现的细节提出其他建议 - 队列,调度程序对象等 - 但这是您实际问题的答案。该线程可以具有由调度程序设置的内部对象,并且调度程序管理队列。随你。它们都是在创建对象后获取某些数据的变体,当然这些对象一直在做。