Programatically check if two threads belong to the same process in Java - java

How do I check if two threads belong to same or different processes programatically? This is the piece of code I have written:
public class MyThread {
public static void main(String[] args) {
TestThread1 obj1 = new TestThread1();
TestThread2 obj2 = new TestThread2();
System.out.println("Current thread:" + Thread.currentThread().getName());
Thread t1 = new Thread(obj1);
t1.start();
Thread t2 = new Thread(obj2);
t2.start();
}
}
class TestThread1 implements Runnable {
#Override
public void run () {
for(int i=0; i<1000 ;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
System.out.println("Current thread:" + Thread.currentThread().getName());
}
}
}
class TestThread2 implements Runnable {
#Override
public void run () {
for(int i=0; i<1000 ;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
System.out.println("Current thread:" + Thread.currentThread().getName());
}
}
}
Here what I understand is thread t1 being created as part of process TestThread1 and thread t2 being created as part of TestThread2 process. But how do i check this programatically?

You mixed the concept of threads and processes.
thread t1 being created as part of process TestThread1 and thread t2
being created as part of TestThread2
Your TestThread1 and TestThread2 are just runnables, that hold information what action should be done by thread. Your t1 and t2 are actual threads, they run in the same process, because you started them in one application. All threads in the application run in same java process, so you can't have a situation where you have two threads referecens and they belong to different processes.
If you start another java application, it will run in a different process, but you won't be able to compare two threads from different processes in a single context.

There is something wrong with your understanding or your use of terminology.
Here what I understand is thread t1 being created as part of process TestThread1 and thread t2 being created as part of TestThread2 process.
First of all, some terminology:
TestThread1 and TestThread2 are classes not processes.
The values in obj1 and obj2 are not processes either. They are instances of the TestThread1 and TestThread2 classes respectively.
If I interpret your question correctly, you are actually asking if there is a way to find out if t1 and t2 share a single Runnable instance. Unfortunately, there isn't a way to do that in pure Java. A Thread object's Runnable is a private field and there is no public getter for retrieving it1.
On the other hand, if you are really asking about processes ...
When you run the application, there will be only one process, and both threads will belong to it.
1 - It is possible to use nasty reflection to retrieve the private field's value, but it is a bad idea. You should look for a way to do whatever you are trying to do that doesn't entail this test ...

Maybe there is an easier way, but you could call getStackTrace() on a thread and then inspect it (search for the run method's frame). However, this will work only for live threads.
PS You use wrong terminology here, what you refer to is not a process, it is just a class that defines the run method which is executed by the thread.

Related

Java: calling a method from the main thread by signaling in some way from another thread

I have an application with 2 threads (the main and another thread t1) which share a volatile variable myVar. Any ideas on how to make the main thread to call a method myMethod by signaling in some way from t1 ?
I implemented it by using ChangeListener and myMethod is called when myVar changes, BUT the method is called from t1, and not from the main thread (note: I need to call this method from the main thread because this is a call to a JavaScript code from Java, so for a security reason only the main thread can do so). Thanks in advance.
You would have to have your main thread spin in a loop on some scalar, I would recommend one of the Atomics that java provides (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html), but you could use volatile if you wanted for this I think.
Each thread can only run sequentially - it's just the way computing works. The way you will handle this, is when the main thread spins in some sort of loop, you eventually check to see if this scalar of yours has been set, and when it has, you want unset the variable and execute your JavaScript. In this particular piece of your code, I think the Atomics have an advantage over the volatile with the use of the compareAndSet operations because using volatile can mess you up a bit between threads if you are trying to check the value in one operation and then set it again in another operation which gives the other thread enough time to set it again - meaning you may miss a call to your JS because the other thread set the variable between the main thread checking it and setting it (although the use of volatile vs Atomics may be interpreted as my opinion).
//main thread
AtomicBoolean foo = new AtomicBoolean(false);
while (...somecondition...){
if(foo.compareAndSet(true, false)){
//execute JS
}
//do some other work
}
and in your T1 thread, just call foo.set(true).
If you expect main to call your JS for each time T1 sets foo to true, then you will have to block in T1 until main has unset foo, or use an AtomicInteger to count how many times T1 has set foo - depending on your needs.
Since both tread sharing the same instance of myVar, you can make both thread to synchronize on the shared variable. Have main to wait on myVar notification before executing myMethod. Later, t1 can notify through variable myVar, and the waiting thread can continue and proceed with the method call.
The following snippet fully demonstrated the idea
public class MainPlay {
public static void main(String[] args) {
MainPlay mp = new MainPlay();
mp.execute();
}
public void execute() {
Thread main = new Thread(mainRunnable, "main");
Thread t1 = new Thread(t1Runnable, "t1");
main.start();
t1.start();
}
public Object myVar = new Object();
public void myMethod() {
System.out.println("MyMethodInfoked.");
}
public Runnable t1Runnable = new Runnable() {
public void run() {
synchronized(myVar) {
try {
System.out.println("[t1] sleep for 1 sec");
Thread.sleep(1000);
System.out.println("[t1] Notifying myVar so Main can invoke myMethod");
myVar.notify();
} catch (InterruptedException e) {
// interupted.
}
}
}
};
public Runnable mainRunnable = new Runnable() {
public void run() {
synchronized(myVar) {
try {
System.out.println("[main] Waiting for t1 to notify...");
myVar.wait();
} catch (InterruptedException e) {
// interrupted.
}
System.out.println("[main] executing main method");
myMethod();
}
}
};
}
And the output is
[main] Waiting for t1 to notify...
[t1] sleep for 1 sec
[t1] Notifying sharedObject so Main can invoke myMethod
[main] executing main method
MyMethodInfoked.
You could use wait/notify blocks to prevent the main thread from continuing until signalled to do so.
static Main main = // ...
static boolean signal = false;
// t1:
// Do work
signal = true;
synchronized (main) {
main.notify();
}
// main:
synchronized (main) {
while (!signal) {
main.wait();
}
}
myMethod();
In case the main thread has nothing else to do, the approach proposed by #searchengine27 results in unnecessary processor load generated by this thread.
So instead going with some AtomicXXX class it would be better to use some of the blocking queues which allow writing of data from one thread (with put()) and consumption of that data by the other. The main queue would block (by calling take() method) if such a queue is empty not using any CPU resources.

Execute code for each new thread?

Is it possible to tell the JVM (or some appropriate object) to execute a given block of code every time a new thread is created?
No, not using standard Java.
Have a look at aspect oriented programming, such as AspectJ. You should probably be able to create a point-cut for the Thread constructor.
Not every time a new thread is created. However, if you use a ThreadPoolExecutor to create new threads, you can specify a ThreadFactory, which can run a specific block of code every time a thread is created by that factory. A simple example (where the block of code to run prints the name of the thread) would look like:
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
System.out.println("New thread created: " + t); //Your block of code
return t;
}
});
Runnable r = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(150);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
for (int i = 0; i < 5; i++) {
executor.submit(r);
}
executor.shutdown();
}
It depends on your use case, but you could also do Java byte code instrumentation. This is, however, normally used for measuring, error tracing, profiling, etc. since it has noticeable performance impacts.
This can be done with ASM, they have a tutorial to get started or take a look at the guide Add Logging at Class Load Time with Java Instrumentation, they explain how to modify the Java code in a way, that code is added each time a method is entered and exited.
In your case you would do this only for special methods, either the Thread() constructor or the invocation of Thread.start().

How do i exit a loop running in threadA after I get a specified input in threadB? in java

import java.io.*;
public class ThreadSanbox {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable(){
#Override
public void run()
{
StopThread stX = new StopThread();
boolean runLoopX = true;
while (runLoopX) {
System.out.println("runLoopX val: "+runLoopX);
runLoopX = stX.getRunLoop();
}
System.out.println("runLoopX val: "+ runLoopX);
}
});
Thread t2 = new Thread(new Runnable(){
#Override
public void run()
{
BufferedReader userInput = new BufferedReader(
new InputStreamReader(System.in));
String userInputStr = "";
StopThread st = new StopThread();
int count = 0;
do {
try {
System.out.println("Enter a value:");
userInputStr = userInput.readLine().trim();
System.out.println("User Input: " + userInputStr);
count++;
} catch (Exception e) {System.err.println(e.toString());}
} while (userInputStr.equals("e") == false);
st.setRunLoop(false);
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (Exception e) {System.err.println(e.toString());}
}
}
class StopThread
{
private boolean runLoop = true;
public synchronized boolean getRunLoop() {return runLoop;}
public synchronized void setRunLoop(boolean val) {runLoop = val;}
}
In the above code I want to run threads t1 and t2. In t2 i want to get input from the keyboard and if the input is e i want to exit the do while and set the value of runLoop to false so that the while loop in t1 also exits. How do I do this?
The problem is that your two threads have two separate instances of StopThread. You need them to share a single instance so that they can communicate.
One way to do this is to create subclasses of Thread or Runnable so that you can pass the shared StopThread instance into each of them in their constructors.
Another way is to make a simple variable in the enclosing class (both threads will be able to 'see' this variable so they can use it to communicate).
You need a way to pass messages between t1 and t2, or to be more specific: From t2 to t1. Either you let t2 know t1 and implement a method for stopping or you use some external common state. I guess the latter is what the StopThread class is thought for. But then you need one instance that is shared between the two threads.
Having a special variable to stop your Runnables is not a bad idea, but it is specific to your classes, so it's not a "general purpose" way to do things. A more general purpose way you should consider would be to check whether the Thread is interrupted. Many threading frameworks, such as Java.util.concurrent, use interrupts to tell running tasks to stop.
So, instead of loops or tests on the boolean runLoop, you'd check Thread.interrupted(). And to tell the Thread to stop, call theThread.interrupt();
Another big advantage is that this will handle many (but, alas, not all) cases where the task is waiting, sleeping, or waiting on I/O.
You should probably implement a form of message passing. For example:
A shared resource that both threads can read and write to
static AtomicBoolean stopLoop = new AtomicBoolean(); // defaults to false
.. in the keyboard listener thread ..
stopLoop.set(true);
.. and in the waiting thread ..
while( stopLoop.get() == false ) { /*wait, consider Thread.sleep()-ing*/ }
The idea is that there's ONE shared, thread-safe resource that both tasks use to communicate. In your case it doesn't have to be atomic because only one thread writes, but its good practice. It should NOT be a thread instance variable. Reference AtomicBoolean.
See http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#interrupt%28%29 ,
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#interrupted%28%29 ,
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#isInterrupted%28%29 and
http://docs.oracle.com/javase/6/docs/api/java/lang/InterruptedException.html

Get all threads that run with a specified Runnable

I have one Runnable that is used by more than one thread:
Runnable myRunnable = new MyWorker();
Thread one = new Thread(myRunnable);
Thread two = new Thread(myRunnable);
one.start();
two.start();
How can I get all threads that are created with myRunnable?
(Of course the example is simplified. I create new threads with myRunnable on several places in different classes.)
Use case (as requested): MyWorkerOfMyPage is a delayed worker that is bound to a page. If the user leaves this page (e.g. by navigating to another page) all threads that belong to MyWorkerOfMyPage should be killed ungracefully as their result is not needed anymore.
As already said best way is to track this yourself. This forces you to get a clear understanding of what you are doing. A good thing if you work with threads ... hmmm ... a good thing in every case ;).
But if you realy want to detect the threads you can use reflection with the Thread class to get the required information. First make the method "getThreads" accessible to get all running Threads, then make the field "target" accessible to get the runnables of the Threads.
Heres an example program (but I would advise against the usage in a real application. You should now what threads you are starting, it might harm compability with future JDKs, might harm portability ...):
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
Runnable myRunnable = new Runnable() {
#Override
public void run() {
try {
System.out.println("Start: " + Thread.currentThread().getName());
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
Thread one = new Thread(myRunnable);
Thread two = new Thread(myRunnable);
one.start();
two.start();
List<Thread> threads = getThreadsFor(myRunnable);
for (Thread thread : threads)
System.out.println("Found: " + thread.getName());
}
private static List<Thread> getThreadsFor(Runnable myRunnable) throws Exception {
Method getThreads = Thread.class.getDeclaredMethod("getThreads");
Field target = Thread.class.getDeclaredField("target");
target.setAccessible(true);
getThreads.setAccessible(true);
Thread[] threads = (Thread[]) getThreads.invoke(null);
List<Thread> result = new ArrayList<Thread>();
for (Thread thread : threads) {
Object runnable = target.get(thread);
if (runnable == myRunnable)
result.add(thread);
}
return result;
}
}
The best way to do this is to track this yourself. Use a global singleton for instance that launches the threads and track which ones you started.
Although my first thoughts are along #Bengt's lines, perhaps you could use Class.isAssignableFrom if you had a list of runnables and you just want to know which ones use your interface.
http://download.oracle.com/javase/6/docs/api/java/lang/Class.html
In Java there is no simple way to find all the places a object is referenced, its something you have to maintain a collection of yourself.
If you want to know this staticly you can Find Usages in your ide.
If you want to know this dynamically you can have the Runnable add the Thread to a collection (and remove it when finished)
Generally speaking, the developer should only create Threads deliberately. i.e. the Developer should know when he/she is creating thread and what those threads will be doing. Its not something you should be trying to track at runtime if you have a good design.

Creating threads in Java

I am a newbie to Java and wondering whether I can create threads in following way.
Desired Java Code :
Class MyClass {
Myclass(){
Statement1;//Create a thread1 to call a function
Statement2;//Create a thread2 to call a function
Statement3;//Create a thread3 to call a function
}
}
Is it possible to create threads like the above code?
The Java Concurrency tutorial includes a page on defining and starting threads. You might want to read through it along with the other pages in the concurrency tutorial.
Echoing GregInYEG, you should check out the tutorial, but the simple explanation is as follows:
You need to create an object class which either extends Thread or implements Runnable. In this class, create (actually, overload) a void method called "run." Inside this method is where you put the code that you would like this thread to execute once it is forked. It could simply be a call to another function if you wish. Then, when you would like to spawn a thread of this type, create one of these objects and call the "start" (not run!) method of this object. eg newThread.start();
It's important to call "start" and not "run" because a run call will simply call the method just like any other, without forking a new thread.
Still, be sure to read up in further detail and there are many more important aspects of concurrency, especially that of locking shared resources.
Yes, it is possible. You want to put your logic for each statement inside a Runnable implementation, and then pass each constructed Runnable to a new instance of Thread. Check out those 2 classes and it should become fairly obvious what you need to do.
I agree with all written here. The thread can be created in a two ways.
To extend thread class . YouTube Tutorial
To implement Runnable Interface YouTube Tutorial
Example for the first method
public class MyThread extends Thread {
public void run()
{
int iterations = 4;
for(int i=0;i<iterations;i++)
{
System.out.println("Created Thread is running " + Thread.currentThread().getId() + " Printing " + i) ;
try {
sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println(e);
}
}
System.out.println("End of program");
}
}
To create a thread
MyThread myThread = new MyThread();
myThread.start();
Second method to implement runnable interface
public class RunnableThread implements Runnable {
#Override
public void run() {
int iterations = 4;
for(int i=0;i<iterations;i++)
{
System.out.println("Runnable Thread is running " + Thread.currentThread().getId() + " Printing " + i) ;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println(e);
}
}
System.out.println("End of program");
}
}
To create a thread
new Thread(new RunnableThread()).start();
So I think you can use both of these methods in you case statements

Categories