I am new to Java Threads. What I am trying to do is from ThreadB object gain access to the instance of a current running thread, ThreadA, and call its method called setSomething.
1) I think I am making harder than it really is
2) I have a null pointer exception so I must be doing something wrong when accessing that method
Here is what I have so far and I have done my due diligence and looked here on StackOverflow for a similar question.
I have a current Thread running in the background:
// assume this thread is called by some other application
public class ThreadA implements Runnable{
private Thread aThread;
public ThreadA(){
aThread = new Thread(this);
aThread.setName("AThread");
aThread.start();
}
#Override
public void run(){
while(true){
// doing something
}
}
public void setSomething(String status){
// process something
}
}
// assume this thread is started by another application
public class ThreadB implements Runnable{
#Override
public void run(){
passAValue("New");
}
public void passAValue(String status){
// What I am trying to do is to get the instance of ThreadA and call
// its method setSomething but I am probably making it harder on myself
// not fully understanding threads
Method[] methods = null;
// get all current running threads and find the thread i want
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for(Thread t : threadSet){
if(t.getName().equals("AThread")){
methods = t.getClass().getMethods();
}
}
//**How do I access ThreadA's method, setSomething**
}
}
Thank you in advance
Allen
Wow why do you make things to much complex?! this is not as hard as you think (killing a dragon in a dark castle!)
okay all you need to do is passing the threadA references to threadB! just this. and let me say that when you call a method from thread b, so it runs by thread b, not the class has been hosted.
class ThreadA implements Runnable {
public void run() {
//do something
}
public void setSomething() { }
}
class ThreadB implements Runnable {
private ThreadA aref;
public ThreadB(ThreadA ref) { aref = ref; }
public void run() {
aref.setSomething(); // Calling setSomething() with this thread! (not thread a)
}
}
class Foo {
public static void main(String...arg) {
ThreadA a = new ThreadA();
new Thread(a).start();
ThreadB b = new ThreadB(a);
new Thread(b).start();
}
}
and here a simple threadtutorial
When or after you instantiate your ThreadB object, give it a reference to your ThreadA object instance. Something like:
ThreadA a = new ThreadA();
ThreadB b = new ThreadB(a);
Then, within the ThreadB code, you can just invoke ThreadA's method by using the reference you have no doubt stored in an instance variable in ThreadB.
Related
I was doing some thought experiment and here is my MyRunnable class:
class MyRunnable implements Runnable {
private final Integer mNumber;
private final CompleteHandler<Integer> mCallback;
public MyRunnable(Integer i, CompleteHandler<Integer> ch) {
mNumber = i;
mCallback = ch;
}
public void run() {
int sum = 0;
for (int i = 1; i <= mNumber; i++) {
sum += i;
}
mCallback.onFinished(sum);
}
}
This will be executed by a background thread which I create on the main thread, under the execute() method
public class Demo implements CompleteHandler<Integer>{
public static void main(String[] args) {
Demo d = new Demo();
d.execute();
}
#Override
public void onFinished(Integer i) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName); // thread-0
}
public void execute() {
MyRunnable mr = new MyRunnable(10, this);
Thread t = new Thread(mr);
t.start();
}
}
As you can see, the MyRunnable calls onFinished() when the task is finished. Is there any way I can have the background thread to call this on the main thread? I know I can do similar thing with callables, but right now I want to know if this is possible with runnables,
thank you
Johannes: Take a look at CompletableFuture...
Brendon: I'm more interested in seeing how it work on code
Here's a simplistic implementation that ignores the issue of exceptions. (Pardon me if it's not actually valid Java code.)
class CompletableFuture<ValueType> {
private Object lock = new Object();
private boolean is_completed = false;
private ValueType completed_value;
public synchronized void complete(ValueType v) {
completed_value = v;
is_completed = true;
notifyAll();
}
public synchronized ValueType await() {
while (! is_completed) {
wait();
}
return completed_value;
}
}
The idea is, the client thread creates a CompletableFuture instance, cf, and somehow passes it to the server thread, possibly along with other args that tell the server thread what to do. Then the client thread goes off to do other, unrelated things.
Meanwhile, the server thread does its thing, eventually produces a result, r, and then it calls cf.complete(r).
At some point, the client thread finishes doing whatever else it was doing, and now it needs the result, so it calls cf.await(). Either one of two things happen at that point:
The server already has set the is_completed flag, in which case, the client immediately gets the result, OR
The server has not yet finished, so the client goes in to the wait() loop to wait for it.
When you're looking at application code, you usually never see the part where the client thread creates the Future object or passes it to the other thread. That usually is all taken care of inside the library call when the client submits a task to a thread pool.
In my school's program solutions for multithreading problems and exercises, classes that implement the Runnable interface are usually given a Thread field, which is automatically instantiated in the following example:
protected Thread thr = new Thread(this);
This field is subsequently used as a means of controlling the Thread over which the class itself is instantiated. For example:
public void stop() {
if (thr != null) thr.interrupt();
}
Which is then used to interrupt Thread objects made with the Runnable class.
A full class example, ported directly from an aforementioned solution, is given below:
package hokej;
import java.awt.Color;
public abstract class AktFigura extends Figura implements Runnable {
protected Thread nit = new Thread(this);
private int tAzur;
private boolean radi;
public AktFigura(Scena s, int xx, int yy,
Color b, int t) {
super(s, xx, yy, b); tAzur = t;
}
protected abstract void azurirajPolozaj();
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
if (!radi) wait();
}
azurirajPolozaj();
scena.repaint();
Thread.sleep(tAzur);
}
} catch (InterruptedException ie) {}
}
public synchronized void kreni() {
radi = true; notify();
}
public void stani() { radi = false; }
public void prekini() {
if (nit != null) nit.interrupt();
}
}
My question is this: How does this work?
Shouldn't the Thread field be a separate object from the object made by calling new Thread(class); in other parts of the program (hence the keyword's name - new)?
Or is this simply a special case that the Java interpreter recognizes in a certain way?
Another question would be the viability of this design as a control method. Is there any simpler/more efficient alternative for controlling a Runnable's thread?
How does this work?
The Thread constructor takes a Runnable, Thread implements this interface. this refers to a Thread instance. So, the statement Thread thr = new Thread(this) is valid, but this practice should be avoided.
Is there any simpler/more efficient alternative for controlling a Runnable's thread?
Thread thread = new Thread(new AktFiguraImpl());
thread.start();
You could control a thread by a class specifically designed for that purpose.
class ThreadController {
public ThreadController(Thread thread, AktFigura figura) { ... }
// methods to manipulate the thread
}
Was wondering if someone could help clear this up for me. (Student)
Say we have two threads, "Thread1" & "Thread2". If Thread1 is executing in method 1 can Thread2 then execute in method2?
void method1() {
synchronized (this) {
}
}
void method2() {
synchronized (this) {
}
}
I'm either thinking yes, Thread2 can enter as "this" is just the instance of that method or no because "this" is the instance of that class and Thread1 holds onto it.
There isn't a monitor associated with a specific method - there's a monitor associated with an object. So if you're trying to synchronize on the same object in both methods, the second thread will block until the first thread releases the monitor.
(Personally I don't like synchronizing on this anyway - I synchronize on a reference to an object that only my class has access to. But that's a different matter.)
Everybody jumped on an obvious answer here. It is a correct answer, but it is not the only correct answer.
The rule is, two threads can not both synchronize on the same object at the same time. But does this refer to the same object in both method calls? We can't tell because you have not shown us the calls. Consider this example:
class Demo {
synchronized void method1() {
...do something...
}
synchronized void method2() {
...do something else...
}
static void caseA() {
final Demo demo = new Demo();
new Thread(new Runnable(){
#Override
public void run() {
demo.method1();
}
}).start();
new Thread(new Runnable(){
#Override
public void run() {
demo.method2();
}
}).start();
}
static void caseB() {
final Demo demo1 = new Demo();
final Demo demo2 = new Demo();
new Thread(new Runnable(){
#Override
public void run() {
demo1.method1();
}
}).start();
new Thread(new Runnable(){
#Override
public void run() {
demo2.method2();
}
}).start();
}
}
In caseA(), the calls to demo.method1() and demo.method2() can not overlap because both calls synchronize on the same object, but in caseB() the two calls are synchronized on two different instances of the Demo class. In caseB() the method1() call and the method2() call can overlap.
You are using this for synchronization, which is an instance of an object. Synchronization always works on some particular instance of object and only one thread at any given time can acquire lock of (synchronize on) a single instance used for synchronization and.
Both threads can access the methods only if they use separate instances of the object containing those methods.
The second thread will block until the monitor is released by the first as synchronization is done on the same object for both methods.
You'd better synchronized on the static object you want to lock.
Here, your method 2 will be executed by thread 2, but the content of the synchronized block in method 2 will not be executed unless thread 1 has unlock this. Since your synchronization is on a block, and not on a method, the method is not synchronized, but the block is.
If you have a static member on which you want work in the synchronized, use it like:
private static List<Object> myList;
void method1() {
synchronized (myList) {
// do something on myList
}
}
void method2() {
synchronized (myList) {
// do something on myList
}
}
No Thread2 will have to wait until Thread1 is finished executing the code in synchronised block. This is because you are using the same object (this) to lock. If you did something like this:
Object lock1 = new Object();
Object lock2 = new Object();
void method1() {
synchronized (lock1) { }
}
void method2() {
synchronized (lock2) { }
}
Then you would be able to have Thread1 execute method1 and Thread2 execute method2.
In my application, I have two threads given ThreadA and ThreadB. ThreadA is a thread that holds and manipulates some data (the producer) and ThreadB is the corresponding consumer thread that reads from ThreadA (read-only).
I want to achieve that ThreadB informs ThreadA to update the data (which may take some time) and when the data is changed, ThreadB should get/request it from ThreadA. As long as ThreadA has not finished updating the data, ThreadB shouldn't wait but continue his work with the current (old) data he has.
Now my idea was to use the observer pattern to inform ThreadB that ThreadA has finished updating
public class ThreadA implements Runnable {
private boolean sometimesTrue = false;
private int[] someBigArray = new int[XXX];
private synchronized int[] getBigArray() {
return this.someBigArray;
}
private void fireListenerDataChanged() {
for(ThreadAListener l : listeners)
l.notify();
}
private synchronized void updateArray() {
//do some stuff on the array that takes a lot of time
}
#Override
public void run() {
while(true) {
if(sometimesTrue) {
updateArray();
}
}
}
public void doUpdate() {
this.sometimesTrue = true;
}
}
public class ThreadB implements Runnable, ThreadAListener {
private int[] bigDataToWorkOn;
private Thread threadA;
public ThreadB(ThreadA threadA) {
this.threadA = threadA;
}
#Override
public void run() {
//do my stuff with bigDataToWorkOn
if(sometimesTrue) {
threadA.doUpdate();
}
}
public void notify() {
this.bigDataToWorkOn = threadB.getBigArray();
}
}
My main goal was to avoid using some kind of BlockingQueue because then afaik ThreadB would wait with his work until ThreadA passes the data in the queue. The same problem would occur if I would call getBigArray in the while-loop in ThreadB because when ThreadA is currently working in updateArray, ThreadA would be locked and ThreadB would also wait for ThreadA to finish. So is this a proper approach?
This approach could be workable solution, except that fact, that you must mark field sometimesTrue with volatile modifier, if you don't want to have infinite loop inside your run() method of ThreadA.
Futhermore, if you don't want your ThreadA be eating 100% of single core, you have to add some delay into loop inside its run() method:
public void run() {
try {
while(true) {
if(sometimesTrue) {
updateArray();
}
Thread.sleep(100);
}
} catch (InterruptedException e) {
// ... do something with e
}
}
Class ThreadTest extends Thread {
public synchronized void run() {
}
public static void main(String args[])
{
Thread t1=new ThreadTest();
Thread t2=new ThreadTest();
t1.start();
t2.start();
}
}
I want to know in above scenario, how locks obtained and on which object?
Does above scenario valid?
As locks are obtained on a calling object in method synchronisation then in above scenario on which object lock will be obtained. One more question who(or which object) invokes the run method?
Thanks,
-Abhishek
t1 has the lock of the t1 instance.
t2 has the lock of the t2 instance.
But your example doesnt make much sense..
Maybe this example will help you:
public class Test extends Thread {
private String name;
public Test(String name) {
this.name = name;
}
public synchronized void run() {
System.out.println(name);
while(true)
{
// loop endless
}
}
public static void main(String args[])
{
Thread t1= new Test("t1");
Thread t2= new Test("t2");
t1.start();
t2.start();
}
}
The output is:
t1
t2
You have started both the threads, but it depends on JVM which thread it might execute, so depending upon the thread which starts executing will acquire the lock first and the second thread cant be on running state till the first thread stops.
but in your case as both are different thread instances they run parallel, as the lock is acquired at the object level.
Your example doesn't make that much sense, because locks are on a per-instance level, not on a per-class level as you might wanted to use them.
I think you got it wrong a bit. The thread is wrapping up the code that is executing commands. These executions often contain access on other objects. That is the point, where locking comes into the game. Each of these objects have a monitor that can be obtained by threads. However, only one thread can obtain the lock at a time. Thus, other threads are enqueued and can access object as soon as the current holder releases it, trivially by exiting a synchronized code block.
I think you might wanted to do something like this:
class ThreadTest extends Thread
{
private final Foo f;
public ThreadTest(Foo f,int i)
{
super(""+i);
this.f = f;
}
#Override
public void run()
{
f.bar();
}
public static void main(String args[])
{
Foo f = new Foo();
Thread t1 = new ThreadTest(f,1);
Thread t2 = new ThreadTest(f,2);
t1.start();
t2.start();
}
public static class Foo
{
public synchronized void bar()
{
System.out.print("hello form Thread ");
System.out.println(Thread.currentThread().getName());
}
}
}
Formal Definition
When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception.
If what you want is to have only one thread execute at a time (What's the point) then you should call a static method and call that from inside your run(), there is only one static method for all object of a class
How do synchronized static methods work in Java?