我是一个初学者,我为我正在从事的项目写了一个事件侦听器工作队列。
我已将其部署在登台服务器上。触发约100个事件后,事件发布后,侦听器将停止呼叫。服务器也没有崩溃。
这是我的实现方式:
@Component
@Scope("prototype")
class ThreadExample implements Runnable
{
String file;
public void setFile(String file)
{
this.file = file;
}
@Override
public void run()
{
readFile(file);
}
public void readFile(String fileName)
{
//logic for reading file
}
}
这里是一个示例用法。
@Component
class ThreadCall
{
@Autowired
ApplicationContext context;
public void testThread()
{
ExecutorService executor2 = Executors.newFixedThreadPool(4);
getFiles()
.stream()
.forEach(f-> {
ThreadExample ex= context.getBean(ThreadExample.class);
ex.setFile(f);
executor2.submit(ex);
});
}
}
我将指针传递给demoHandler作为事件处理程序,因为它们需要访问基础sql实例。每个工作队列使用相同的demoHandler是否存在问题?
我无法为自己的生活弄清楚哪里出了问题!除了处理程序代码中的错误之外,我的代码中是否存在导致我所有工作人员都无法使用的错误?
答案 0 :(得分:0)
“在go worker / event系统中,worker是否应该访问同一结构(通过指针)来工作?” 不,这不是问题。如果您的处理程序中的代码访问critical section,将是一个问题,但是我认为这不会导致您的程序被阻塞。
您的服务器也不会崩溃或阻塞,因为没有触发任何紧急情况,并且您的程序正在侦听和执行独立的goroutine,它们是轻量级的执行线程。
可能必须与您用于发送和接收事件的频道有关。
默认情况下,发送和接收到channel处于阻止状态。这意味着当您从某个频道发送或接收消息时,它将阻塞其goroutine,直到另一侧准备就绪为止。
对于buffered channels,在缓冲区已满时发送块,而在缓冲区为空时接收块,如在您的流通道中一样:
var stream = make(chan *Event, 100)
您说:“触发了大约100个事件后,事件发布后,侦听器就不再被呼叫”。
因此,如果调用“发布”函数并在“流”通道缓冲区已满时执行stream <- ev
,它将阻塞直到该通道有位置接收另一个元素为止。
我建议您阅读一些有关non-blocking channel operations的信息。
可能是在您的实际使用代码的某些部分中发生了封锁。