I have a class that implements Runnable. For logging reasons I want to know the Thread that has been used to run the class. In that case would it be best to do
public class WebSocketHandle implements Runnable {
private Thread myThread; // access to thread for logging
public void start() {
myThread = new Thread(this);
myThread.start();
}
}
Then in the method that creates these I do something like:
public void newSocket(Socket socket)
{
WebSocketHandle handle = new WebSocketHandle(this, socket,_identity);
_sockets.add(handle);
EventLog.write("Socket assigned for new connection (" + _sockets.size() + ") " + handle.toString() + ". No value received yet yet...", getClass().getName(), "register");
// Start thread listening for data
new Thread(handle).start();
}
Or is it best to have something like:
public class WebSocketHandle implements Runnable {
private String myThread;
public void setThreadOwner(string threadId) {
myThread = threadId;
}
}
Then it would be used as such:
WebSocketHandle handle = new WebSocketHandle();
Thread newThread = new Thread(handle);
newThread.start();
handle.setThreadOwner(handle.toString());
I can't help but feel the second option is better practice but the code to write seems clumsier??
EDIT: In response to Aaron's comments:
This is for a Web server socket handling code so the Thread will be running indefinetly. I had not considered using ThreadPools so maybe that is something I need to consider
I log various activities (i.e. data received and sent) in the the WebSocketHandle class so I wanted to tie the logging events to the Thread instance that it is running on. To do that I found the easiest way was to log the thread.toString() as part of the log output.
You can simply call Thread.currentThread() to get the thread which is executing the code right now.
To help identifying a thread, use new Thread("some useful name");
[EDIT] Both of your approaches have some drawbacks. The first approach always creates a thread, so you can't execute the runnable in, say, a thread pool. And eventually, you will want to do that. Unfortunately, when you find out that you do, your application will have become very complex and it will be hard to change.
Also the "thread" doesn't help you much; it's usually irrelevant which thread started something. When looking for bugs, you want to know which piece of code executed a method. So it would make more sense to pass a Logger into start().
That said, what do you mean by "access to thread for logging"? What information does the anonymous thread created in start() contain which might be useful for logging? Since it has a generated name and you still don't know who called start(), the first approach looks completely useless to me.
The second approach allows you to give the Runnable a name but a) it doesn't compile and b) doesn't make any sense either (not mentioning the fact that the variable names are confusing).
To get the class of something, you can call getClass().getName(); there is no point in setting the class name of the instance using a setter. So the second approach is dangerously confusing and it violates the DRY principle.
Also, it doesn't give you much useful information for logging: It doesn't tell you who created the instance of MyClass and if you wanted a logger for MyClass, you can simply use this line:
private Logger log = LoggerFactory.getLogger(getClass());
There is no need for the setter.
So my conclusion is that both approaches should be avoided.
Related
I have my following job in Liferay 7.1 :
#Component(
immediate = true, property = {"cron.expression=0 5 10 * * ? *"},
service = CustomJob.class
)
public class CustomJob extends BaseMessageListener {
....
#Override
protected void doReceive(Message message) throws Exception {
// HERE I CALL A SERVICE FUNCTION TO INACTIVATE USER, SEND MAILS, READ FILES TO IMPORT DATA
RunnableService rs = new RunnableService();
rs.run();
}
....
}
And my RunnableService :
public class RunnableService implements Runnable {
#Override
public synchronized void run() {
// DO MY STUFF
}
}
The job is working great, but another instance of the job can be started even when the service execution from the first call hasn't finished.
Is there any solutions to kill the first process ?
Thanks,
Sounds like there are several options, depending on what you want to achieve with this:
You shouldn't interrupt threads with technical measures. Rather have your long-running task check frequently if it should still be running, otherwise terminate gracefully - with the potential of cleaning up after itself
You can implement your functionality with Liferay's MessageBus - without the need to start a thread (which isn't good behavior in a webapp anyway). The beauty of this is that even in a cluster you end up with only one concurrent execution.
You can implement your functionality outside of the Liferay process and just interact with Liferay's API in order to do anything that needs to have an impact on Liferay. The beauty of this approach is that both can be separated to different machines - e.g. scale.
I have defined this kind of Android Java class, where native function baresipStart() never terminates:
package com.tutpro.baresip;
public class BaresipThread extends Thread {
public void start() {
baresipStart();
}
public void kill() {
baresipStop();
}
public native void baresipStart();
public native void baresipStop();
}
I then call its start() function from another Java class:
BaresipThread thread;
thread = new BaresipThread();
thread.start();
The result is that baresipStart() function starts to run fine, but rest of the application becomes completely unresponsive.
Why is that and how to fix the code so that baresipStart() function runs in the background without stopping all other activity?
Thread.start() is responsible for actually creating the new thread of execution and setting it running. By overriding it as you did, you cause it to instead run baresipStart(), in the thread that invokes start().
Instead of overriding start(), you should override run(). This method is what defines the work to be performed in the new thread of execution.
Furthermore, if native method baresipStart() indeed never returns then you have a problem. Your application cannot terminate while it has any active threads. Supposing that you intend for baresipStop() to cause the thread to finish, you should arrange for baresipStart() to return (or to throw an unchecked exception) when execution is terminated by an invocation of baresipStop(). Do be aware, however, that those native methods need to be thread-safe, because they will, perforce, be invoked by different Java threads.
Thanks for your explanation. I got the new baresip thread started by removing BaresipThread object altogether and replacing the three lines above with this:
new Thread(new Runnable() {
public void run() {
baresipStart();
}
}).start();
User can stop the resulting process via its user interface after which the application is terminated.
A load of tasks are submitted to my application but it keeps hanging and I track it down to this code:
uk.ac.shef.wit.simmetrics.tokenisers.TokeniserWhitespace.tokenizeToArrayList(TokeniserWhitespace.java:133)
uk.ac.shef.wit.simmetrics.similaritymetrics.CosineSimilarity.getSimilarity(CosineSimilarity.java:142)
com.jthink.songkong.match.Scorer.compareValues(Scorer.java:74)
com.jthink.songkong.match.Scorer.calculateTitle(Scorer.java:704)
com.jthink.songkong.match.Scorer.matchRecordingOrTrackTitle(Scorer.java:652)
com.jthink.songkong.match.Scorer.calculateTrackScoreWithinRelease(Scorer.java:538)
com.jthink.songkong.match.Scorer.scoreMatrix(Scorer.java:396)
com.jthink.songkong.match.Scorer.calculateReleaseScore(Scorer.java:1234)
It is basically an string matching algorithm in a 3rd party library but it does not throw ThreadInterruptedException so does this mean I cannot interrupt it, but is certainly a long running process having run for 30 minutes. I have a reference to the thread monitoring this code but is there any way to stop it.
Of course I am looking to fix the 3rd party library but in the meantime I need a way to stop my application hanging by cancelling these hanging tasks. What makes it worse for me is that I use Hibernate, and a hibernate session is created in this stack and then because this TokeniserWhitespace method never finishes my session (and hence database connection) is never released therefore eventually I ran out of database connections and the application completely hangs.
I would try Thread.interrupt() as even though the interrupted exception isn't thrown it doesn't necessarily mean that the 3rd party library doesn't handle it correctly in some other way. If that doesn't work then I would consider Thread.stop() even though it is depricated in the hopes that the library's design can handle sudden termination and doesn't end up in an inconsistent state (due to the transactional nature in which you are using it, I doubt there are many shared objects to get corrupted). Thread.stop() will cause the event to stop immediately and throw a ThreadDeath exception no matter what it is doing and it was deprecated by Sun due to the chance of leaving shared objects in an unknown and inconsistent state.
You can can use the Akka library to wrap the problematic code - this will let you kill and restart the code if it hangs.
import scala.concurrent.Future;
public interface ProblemCode {
public Future<String> stringMatch(String string);
}
public class ProblemCodeImpl implements ProblemCode {
public Future<String> stringMatch(String string) {
// implementation
}
}
import akka.actor.ActorSystem;
import akka.actor.TypedActor;
import scala.concurrent.Await;
import scala.concurrent.duration.Duration;
import akka.actor.TypedProps;
public class Controller {
private final ActorSystem system = ActorSystem.create("Name");
private ProblemCode problemCodeActor = getProblemCodeActor();
private ProblemCode getProblemCodeActor() {
return TypedActor.get(system).typedActorOf(new TypedProps<ProblemCodeImpl>(ProblemCode.class, ProblemCodeImpl.class));
}
public String controllerStringMatch(String string) {
while(true) {
try {
// wait for a Future to return a String
return Await.result(problemCodeActor.stringMatch(string), Duration.create(5000, TimeUnit.MILLISECONDS));
} catch (TimeoutException e) {
// Await timed out, so stop the actor and create a new one
TypedActor.get(system).stop(problemCodeActor);
problemCodeActor = getProblemCodeActor();
}
}
}
}
In other words, the controller calls stringMatch on the problem code that has been wrapped in an actor; if this times out (5000 milliseconds in my example) you stop and restart the actor and loop through the controller method again.
ProblemCode will only execute one method at a time (it will enqueue subsequent invocations), so if you want to concurrently execute stringMatch you'll need to create multiple actors and create a router out of them / place them in a queue / etc.
I am working on a webserver written in Java. The web server is handling websocket communication with the clients and therefore we have a class called ClientHandler that has a socket and id as instance variables. The ClientHandler will need to have a function that will listen for messages from the clients. This function needs to work in paralell to the rest of the server, and since the "reading of messages" is a thread blocking function, we need a separate thread for this.
Here's the two alternative ways of implementing this:
public class ClientHandler implements Runnable{
//Instance variable
public Thread listener = new Thread(this);
.
.
.
public void run() {
while (!Thread.interrupted()){
//Listening code here
}
}
}
And then start the listener thread by writing
clientHandler.listener.start();
And stop it by writing
clientHandler.listener.interrupt();
Or this method:
public class ClientHandler {
//Instance variable
private Thread listenerTread;
private boolean alive; //set to true in constructor
.
.
.
public void listenToClient() {
listenerTread = new Thread(new Runnable() {
#Override
public void run(){
while (!alive){
//Listening code here
}
}
});
}
}
and then start the thread by calling the function listenToClient()
clientHandler.listenToClient();
and stop it by switching alive = false.
I have tried to find someone explaining the best solution, but most comparisons are between implementing Runnable or extending Thread. Is the any downsides to using either of the methods above? What method is best if I want to have multiple threads in one class?
I'm not sure you want to explicitly create a Thread instance. Why don't you try using a ThreadPoolExecutor to which you submit the tasks for execution. Read here more about thread pool. http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
Since you can have many clients, using a thread pool may improve the performance of your application.
You have two tasks. One is to listen for new connections and initiate serving of that connections. Second is to actually serve a connection. The decision to serve each connection within a separate thread is an implementation detail of the second task. In principle, it can be served in other ways, with a thread pool or with async IO. So this implementation detail should be hidden inside the code of the second task and must not be visible to the code of the first task. So use the second way.
do you happen to know explanation why java security manager doesn't forbid creating new threads or starting them? new FileWriter is under security manager, but neither new Thread(), nor threadInstance.start() isn't uneder security manager, and are possible to call.
Wouldn't it be usefull to forbid it ?
Would it be hard to implement ?
Or creating and starting new Thread isn't so relevant to forbid it?
It isn't possible to define a security policy that will prevent code from creating and starting a new thread using the standard Java SecurityManager.
Let's say you have the following code:
public class Test {
public static void main(String [] args) {
System.out.println(System.getSecurityManager() != null ? "Secure" : "");
Thread thread = new Thread(
new Runnable() {
public void run() {
System.out.println("Ran");
}
});
thread.start();
}
}
and you run it with the following command:
java -Djava.security.manager -Djava.security.policy==/dev/null Test
it will run just fine and output:
Secure
Ran
even though we set the security policy to /dev/null, which will grant zero permissions to any code. It's therefore impossible to grant fewer permissions to prevent the code from creating that thread.
This is because the the standard java.lang.SecuritManager only performs an permission check if code tries to create a thread in the root ThreadGroup. At the same time, the SecurityManager's getThreadGroup mehtod always returns the current Thread's thread group, which will never be the root thread group, so permission to create a new Thread will always be granted.
One way to get round this is to subclass java.lang.SecurityManager and override the getThreadGroup method to return the root ThreadGroup. This will then allow you to control whether code can create threads based on whether it has the java.lang.RuntimePermission "modifyThreadGroup".
So if we now define a subclass of SecurityManager as follows:
public class ThreadSecurityManager extends SecurityManager {
private static ThreadGroup rootGroup;
#Override
public ThreadGroup getThreadGroup() {
if (rootGroup == null) {
rootGroup = getRootGroup();
}
return rootGroup;
}
private static ThreadGroup getRootGroup() {
ThreadGroup root = Thread.currentThread().getThreadGroup();
while (root.getParent() != null) {
root = root.getParent();
}
return root;
}
}
and then run our command again, but this time specifying our subclassed ThreadSecurityManager:
java -Djava.security.manager=ThreadSecurityManager -Djava.security.policy==/dev/null Test
We get an exception in our Test class when we try to create the new thread:
Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
There is an access check performed in the Thread constructor to see if the caller has permission to change the ThreadGroup that the new thread would be added to. That is how you would implement a security policy to forbid creation of new threads.
(And there is another check on the creation of ThreadGroups ... that checks if you have permission to add the new group to its parent.)
So to answer your questions:
Why java security manager doesn't forbid neither creating new Thread() nor starting it?
The reason is that your JVM's current security policy allows the parent thread to modify its ThreadGroup. You should be able to modify that policy setting to prevent that, and hence prevent creation of child threads.
Wouldn't it be useful to forbid it?
It is. It is unwise to allow untrusted code to create / start threads because: 1) threads once started cannot be safely killed, and 2) creating / starting lots of threads can bring the JVM (and maybe the OS) to its knees.
Would it be hard to implement?
From your perspective, just change the policy.