在go worker / event系统中,worker是否应该访问同一结构(通过指针)进行工作?

时间:2019-02-04 13:22:53

标签: go events channels

我是一个初学者,我为我正在从事的项目写了一个事件侦听器工作队列。

我已将其部署在登台服务器上。触发约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是否存在问题?

我无法为自己的生活弄清楚哪里出了问题!除了处理程序代码中的错误之外,我的代码中是否存在导致我所有工作人员都无法使用的错误?

1 个答案:

答案 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的信息。

可能是在您的实际使用代码的某些部分中发生了封锁。