...
This method interrupts the current thread, however, it only stops the thread because the thread logic polls the interrupted flag using the method Thread.interrupted()
, and shuts down when it is interrupted.
Noncompliant Code Example (
...
Connection per thread)
This noncompliant code example shows a thread-safe variant of the SocketReader
class DBConnector
that creates a Socket
JDBC connection per thread, that is, the socket connection belonging to one thread is not shared amongst multiple threads. This is a common scenario in applications that must place requests to several servers simultaneously, without using any lockingby other threads.
Code Block | ||
---|---|---|
| ||
// Thread-safe SocketReader public class SocketReaderDBConnector implements Runnable { private final String hostquery; private final int port; SocketReaderDBConnector(String host, int portquery) { this.hostquery = hostquery; this.port = port; } public void run() { Socket socket = nullConnection con; try { socketcon = new Socket(host, port); } catch (UnknownHostException e) { // Forward to handler DriverManager.getConnection("jdbc:myDriver:name", "username","password"); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(query); } catch (IOExceptionSQLException e) { // Forward to handler } // Do... some useful work } } } |
This design does not permit a client to close the socket when a cancel a task by closing it if the corresponding thread is blocked , or is performing some time consuming activityon a long running activity such as a join query. Furthermore, it is important to provide a mechanism to close connections to prevent thread starvation caused because of the limited number of database connections available in the pool. Similar task cancellation mechanisms are required when using objects local to a method, such as sockets.
Compliant Solution (ThreadLocal)
This compliant solution uses a ThreadLocal
wrapper around the socket connection so that a thread that calls initialValue()
obtains a unique socket connection instance. The advantage of this approach is that a shutdownSocketshutdownConnection()
method can be provided so that clients external to the class can also shutdown close the socket connection when it the corresponding thread is blocked, or is performing some time consuming activity.
Code Block | ||
---|---|---|
| ||
class SocketReaderDBConnector implements Runnable { privatefinal staticString ThreadLocal<Socket>query; connectionHolder = new ThreadLocal<Socket> DBConnector(String query) { this.query = query; } private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() { SocketConnection socketconnection = null; @Override public SocketConnection initialValue() { try { connection = DriverManager.getConnection socket = new Socket("defaultHostjdbc:driver:name", 25"username","password"); // 25 is the default port to connect to } catch (UnknownHostException e) { // Forward to handler } catch (IOExceptionSQLException e) { // Forward to handler } return socketconnection; } @Override public void set(SocketConnection sockcon) { if(sockconnection == null) { // Shuts down socket when null value is passed try { socketconnection.close(); } catch (IOExceptionSQLException e) { // Forward to handler } } else { } else socket{ = sock; // Assigns Socket with caller specifiedconnection hostname= andcon; port } } }; public static SocketConnection getSocketConnectiongetConnection() { return connectionHolder.get(); } public static void shutdownSocketshutdownConnection() { // Allows client to close socket anytime connectionHolder.set(null); } public void run() { SocketConnection socketdbConnection = getSocketConnectiongetConnection(); // Do some useful workStatement stmt; try { stmt = dbConnection.createStatement(); ResultSet rs = stmt.executeQuery(query); } catch (SQLException e) { // Forward to handler } // ... } } |
Risk Assessment
Trying to force thread shutdown can result in inconsistent object state and corrupt the object. Critical resources may also leak if cleanup operations are not carried out as required.
...