java - Pre-initializing a pool of worker threads to reuse connection objects (sockets) -
i need build pool of workers in java each worker has own connected socket; when worker thread runs, uses socket keeps open reuse later. decided on approach because overhead associated creating, connecting, , destroying sockets on ad-hoc basis required overhead, need method pool of workers pre-initializaed socket connection, ready take on work while keeping socket resources safe other threads (sockets not thread safe), need along these lines...
public class sockettask implements runnable { socket socket; public sockettask(){ //create + connect socket here } public void run(){ //use socket here } }
on application startup, want initialize workers and, hopefully, socket connections somehow too...
myworkerpool pool = new myworkerpool(); for( int = 0; < 100; i++) pool.addworker( new workerthread()); as work requested application, send tasks worker pool immediate execution...
pool.queuework( new sockettask(..));
updated working code
based on helpful comments gray , jontejj, i've got following code working...
sockettask
public class sockettask implements runnable { private string workdetails; private static final threadlocal<socket> threadlocal = new threadlocal<socket>(){ @override protected socket initialvalue(){ return new socket(); } }; public sockettask(string details){ this.workdetails = details; } public void run(){ socket s = getsocket(); //gets threadlocal //send data on socket based on workdetails, etc. } public static socket getsocket(){ return threadlocal.get(); } } executorservice
executorservice threadpool = executors.newfixedthreadpool(5, executors.defaultthreadfactory()); int tasks = 15; for( int = 1; <= tasks; i++){ threadpool.execute(new sockettask("foobar-" + i)); } i approach several reasons...
- sockets local objects (via threadlocal) available running tasks, eliminating concurrency issues.
- sockets created once , kept open, reused when new tasks queued, eliminating socket object create/destroy overhead.
one idea put sockets in blockingqueue. whenever need socket threads can take() queue , when done socket put() on queue.
public void run() { socket socket = socketqueue.take(); try { // use socket ... } { socketqueue.put(socket); } } this has added benefits:
- you can go using
executorservicecode. - you can separate socket communication processing of results.
- you don't need 1-to-1 correspondence processing threads , sockets. socket communications may 98% of work maybe no gain.
- when done ,
executorservicecompletes, can shutdown sockets dequeueing them , closing them.
this add additional overhead of blockingqueue if doing socket communications, won't notice it.
we don't believe threadfactory addresses our needs ...
i think make work if used thread-locals. thread factory create thread first opens socket, stores in thread-local, calls runnable arg of work socket, dequeuing jobs executorservice internal queue. once done arg.run() method finish , socket thread-local , close it.
something following. it's bit messy should idea.
executorservice threadpool = executors.newfixedthreadpool(10, new threadfactory() { public thread newthread(final runnable r) { thread thread = new thread(new runnable() { public void run() { opensocketandstoreinthreadlocal(); // our tasks socket thread-local r.run(); getsocketfromthreadlocalandcloseit(); } }); return thread; } })); so tasks implement runnable , like:
public socketworker implements runnable { private final threadlocal<socket> threadlocal; public socketworker(threadlocal<socket> threadlocal) { this.threadlocal = threadlocal; } public void run() { socket socket = threadlocal.get(); // use socket ... } }
Comments
Post a Comment