1

I have a resource (in my case zmq socket, but this detail can be ignored). The resource is not thread safe, and can be used only from a thread, that opened connection.

I want to use it in ScheduledThreadPoolExecutor. So my ideal workflow would be:

  • thread on startup opens a connection
  • every worker task should implement and interface (socketAware)
  • socket from current thread gets injected to a worker via the method of the interface.

    ScheduledExecutorService service = Executors.newScheduledThreadPool(5, new SocketAwareThreadFactory(socket));
    service.scheduleAtFixedRate(new SocketAwareRunable(), 0, 5, TimeUnit.SECONDS);
    
    
    public class SocketAwareThreadFactory implements ThreadFactory {
        private final Proxyable socket;
    
        SocketAwareThreadFactory(Proxyable socket) {
            this.socket = socket;
        }
    
        @Override
        public Thread newThread(@Nonnull Runnable action) {
            return new SocketAwareThread(socket, action);
        }
    }
    
    public class SocketAwareThread extends Thread {
    
        private final Socket proxy;
    
        public SocketAwareThread(Proxyable socket, Runnable action) {
            super(action);
            proxy = socket.proxy();
        }
    
        @Override
        public void run() {
            proxy.open();//connection opens here
            super.run();
        }
    }
    

Is there any way now to propagate opened socket back to every Runable that is executed by this thread, except of using reflection ?

It looks like ThreadPoolExecutor.beforeExecute could do the trick, but it does not work with ScheduledThreadPoolExecutor, since runnable is not what I have submitted, but something already decorated.

ucMedia
  • 4,105
  • 4
  • 38
  • 46
Igor Piddubnyi
  • 134
  • 4
  • 19
  • You can just use a common (static?) variable with access to it synchronized so it is only initialized once. – daniu Mar 18 '19 at 18:20
  • have you considered using a ThreadLocal shared between your custom thread implementation and your task target type? Your `SocketAwareRunable` would get the Socket of the ThreadLocal. – Mark Mar 18 '19 at 19:29

0 Answers0