Waking up a sleeping thread using reflection - java

I've got a problem as follows: I've got the next class:
Public class foo{
Thread runningThread = null;
...
public static void start() {
runningThread = new RunningThreadImpl();
runningThread.start();
runningThread.join();
}
public static void stop() {
this.runningThread.stop();
}
}
And:
Public class runningThreadImpl implements Runnable {
...
public void run() {
while (shouldRun()){
sleep(... A long long time);
}
}
public void stop() {
shouldRun = false;
}
I've got a class using foo, And now i want it to stop. The above code defined inside a given jar, Which means i cannot edit it. But i thought about using Reflection in order to interrupt the Thread and "Wake" him up so i won't have to wait.
So far i've gotten this far:
Field field = foo.getInstance().getClass().getDeclaredField("runningThread");
field.setAccessible(true);
But i don't now what to do now. How can i use the Field in order to interrupt a thread? Is it even possible?

You could create a new class called FooHelper in the same package as Foo like so:
package same.package.as.foo;
public class FooHelper {
private final Foo foo;
public FooHelper(Foo foo) {
this.foo = foo;
}
public void stop() {
this.foo.stop();
this.foo.runningThread.interrupt();
}
}
Construct a FooHelper passing it the instance of Foo, and call the FooHelper's stop() method.

Related

Junit for runnable class and Queue

I have a Processor class which implements Runnable.
The first method
Public Processor implements Runnable{
//"Event" is the name of this queue
PersistentQueue<Event> persistentQueue = new PersistentQueue<>("Event");
//add the Event POJO to the persistentQueue
public void addToQueue(Event, event) {
persistentQueue.add(event);
}
The persistentQueue is to store Event POJO
And the run method
public void run() {
while (true) {
if (!persistentQueue.isEmpty()) {
Event peekEvent = persistantQueue.peek();
sendRequest(peekEvent);
}
}
}
public void sendRequest(Event, event){
// do something to send the event
}
For the first addToQueue method I wrote the test
public class ProcessorTest {
private Event event;
private Processor m_Processor;
#Before
public void setup() throws IOException {
//the Processor class is a singleton
m_Processor = Processor.getProcessor();
event = new Event();
}
#Test
public void test(){
PersistentQueue<Event> persistentQueue = new PersistentQueue<>
("Event");
m_Processor.addToQueue(event);
assertEquals(1, persistentQueue.size());
}
}
But the queue size is 0 not 1. I dont know what's the problem. And I also have question about how to test the run method?
In your test method, you created a new queue that has nothing to do with your m_Processor instance; it goes unused entirely. You need to change your code so you can get the PersistentQueue instance contained inside your m_Processor instance. Assuming you have a getter method called getPersistentQueue inside Processor, then you can use the following:
#Test
public void test() {
m_Processor.addToQueue(event);
assertEquals(1, m_Processor.getPersistentQueue().size());
}

Access anonymous Runnable instance in Mockito / Powermock

This is my test code:
Activity activityMock = Mockito.mock(TestActivity.class);
doAnswer(new Answer() {
#Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Object[] args = invocationOnMock.getArguments(); // ->>>> args contains one Foo instance called "foo"
return invocationOnMock;
}
}).when(activityMock).runOnUiThread(any(Runnable.class));
runDialogOnUiThread(activityMock, new Foo());
To the following production code:
public static void runDialogOnUIThread(final Activity activity, final Foo foo) {
activity.runOnUiThread(new Runnable() {
#Override public void run() {
doSmth();
}
});
}
See my comment in the test code. I expect invocationOnMock.getArguments() to return the Runnable instance, but it is returning the Foo instance (Which makes absolutely no sense to me)?
I thought
doAnswer(new Answer(){..}).when(b).bMethod(any(C.class))
intercepts when bMethod() is called anywhere on b and it will pass the instance of C.class to the doAnswer() to make it available in the "new Answer().."-Callback..
How can I access the anonymous Runnable instance, which is created in the production code?
I'm guessing that your anonymous Runnable instance is defined in Foo, right?
Here's some code I wrote to try to reproduce your issue:
public class MockitoTest {
#Test
public void test() {
final Activity activityMock = Mockito.mock(TestActivity.class);
doAnswer(new Answer() {
#Override
public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
final Object[] args = invocationOnMock.getArguments();
System.out.println("Is argument a Runnable? " + (args[0] instanceof Runnable));
System.out.println("What is the argument toString()? " + args[0].toString());
return invocationOnMock;
}
}).when(activityMock).runOnUiThread(any(Runnable.class));
runDialogOnUIThread(activityMock);
}
public void runDialogOnUIThread(final Activity activity) {
final Runnable r = new Runnable() {
#Override public void run() {
System.out.println("***");
}};
activity.runOnUiThread(r);
}
public static interface Activity {
void runOnUiThread(Runnable r);
}
public static class TestActivity implements Activity {
#Override
public void runOnUiThread(final Runnable r) { r.run(); }
}
}
Pretty much the same thing, but it is trimmed down to illustrate where I think you are getting confused.
The output is:
Is argument a Runnable? true
What is the argument toString()? stackoverflow.MockitoTest$2#6b143ee9
Note that the second output contains MockitoTest for the toString() output and nothing about it being a Runnable. That's because the toString() method is not being explicitly defined in the anonymous Runnable.
Let's change the Runnable as follows:
final Runnable r = new Runnable() {
#Override public void run() {
System.out.println("***");
}
#Override public String toString() {
return "ANON RUNNABLE";
}
};
Then the output is:
Is argument a Runnable? true
What is the argument toString()? ANON RUNNABLE
What I suspect you were getting tripped up on is that the toString() output looked like the same class name as the class that the anonymous Runnable was created in.

Objects and getting parents methods

Here is the best way I could summarise my situation:
Class1 makes new Thread(new Class2)
Is there a way from inside objects 2 code I can access non-static public methods from object 1?
Not sure if I have explained myself enough but I can answer any questions that could help describe it better
Edit: To elaborate Class1 is a multithreaded server and Class2 is the WorkerClass and i want to access Class1.stop() to stop the server from inside the workerClass
There are at least 3 ways to do this:
(1) Use an anonymous inner class:
public class Class1 {
public void foo() {}
public void bar() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
foo();
}
});
}
}
(2) Use a named inner class:
public class Class1 {
public void foo() {}
public void bar() {
Thread t = new Thread(new MyRunnable());
}
private class MyRunnable implements Runnable {
#Override
public void run() {
foo();
}
}
}
(3) Pass this to the constructor of another top-level class:
public class Class1 {
public void foo() {}
public void bar() {
Thread t = new Thread(new MyRunnable(this));
}
}
class MyRunnable implements Runnable {
private Class1 class1;
public MyRunnable(Class1 class1) {
this.class1 = class1;
}
#Override
public void run() {
class1.foo();
}
}

Synchronizing overlapping sets of methods

Imagine a Java class with three methods:
master()
foo()
bar()
I want to synchronize master() and foo() and also master() and bar(), without synchronizing foo() and bar(). It can be done will a separate lock for every pair of synchronized methods, but my actual code has many more than three methods so I was hoping there's a way to do it without so many lock objects.
You are essentially describing a ReadWriteLock. Every two methods are allowed to run simultaneously (a "read lock"), except for master(), which excludes all others (a "write lock"):
public class MyClass {
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock r = rwLock.readLock();
private final Lock w = rwLock.writeLock();
public void master() {
w.lock();
// do stuff
w.unlock();
}
public void foo() {
r.lock();
// do stuff
r.unlock();
}
public void bar() {
r.lock();
// do stuff
r.unlock();
}
}
You can use synchronized on any Object. So, you can create a separate lock for the methods:
public class Lock {
private final Object master_foo = null;
private final Object master_bar = null;
public void master() {
synchronized(master_foo) {
synchronized(master_bar) {
...
}
}
}
public void foo() {
synchronized(master_foo) {
...
}
}
public void bar() {
synchronized(master_bar) {
...
}
}
}
I would go with Mureinik's answer, but just for the heck of it, here's another way you can set up read/write synchronization (untested):
public class Test {
private final Semaphore semaphore = new Semaphore(Integer.MAX_VALUE);
public void master() {
semaphore.acquireUninterruptibly(Integer.MAX_VALUE);
try {
//...
} finally {
semaphore.release(Integer.MAX_VALUE);
}
}
public void foo() {
semaphore.acquireUninterruptibly();
try {
//...
} finally {
semaphore.release();
}
}
public void bar() {
semaphore.acquireUninterruptibly();
try {
//...
} finally {
semaphore.release();
}
}
}

Passing a Runnable object to a class extending Thread class and then starting it prints unexpected result

I heard about an interview question from one of my friend.
What happens when we pass a Runnable object to an object of a class extending Thread class and start the class.
public class A extends Thread {
Runnable obj;
public A(Runnable obj) {
this.obj=obj;
}
public void run() {
System.out.println("Printing A")
}
}
public class B implements Runnable {
public void run() {
System.out.println("Printing B");
}
}
public class MainApp {
public static void main() {
B b = new B();
A a = new A(b);
a.start();
}
}
Now it outputs Printing A
I was expecting Printing B as it is a perfect analogy to
Thread obj = new Thread(Runnable runnableObj)
Can someone please explain me this weird output??
Thread has a run method which essentially calls runnable.run(). Except that in your class A you have overriden that method to do something else.
So runnable.run() is not called any longer...
You are creating an instance of class A (Now it is a Thread).
Then you are calling start() of that Thread using instance a.
You are just passing a Runnable object as a normal instance variable to class A.
There is nothing complicated in that.
The result is normal.
With a tiny adjustment your code runs as expected.
public class A extends Thread {
Runnable obj;
public A(Runnable obj) {
this.obj = obj;
}
public void run() {
System.out.println("Printing A");
obj.run();// <---- I added this.
}
}
public class B implements Runnable {
public void run() {
System.out.println("Printing B");
}
}
public void test() {
B b = new B();
A a = new A(b);
a.start();
}
The problem is that you are overriding the run() method on Thread and never pass the Runnable obj to super(). Try this:
public class A extends Thread {
public A(Runnable obj) {
super(obj);
}
public class B implements Runnable {
public void run() {
System.out.println("Printing B");
}
}
public void test() {
B b = new B();
A a = new A(b);
a.start();
}
}

Categories

Resources