I am developing a client-server in java and I encountered problem passing a custom Runnable implementation as argument from an object to another.
The problem is that the Runnable code is evaluated (not executed) at definition but I want it to be evaluated at invocation.
Is there any way to achieve this behavior?
Here the code affected by this problem:
Custom Runnable implementation
public abstract class ChallengeReportDelegation implements Runnable
{
private ChallengeReport fromChallengeReport = null;
private ChallengeReport toChallengeReport = null;
#Override
public abstract void run();
public ChallengeReport getFromChallengeReport()
{
return fromChallengeReport;
}
public ChallengeReport getToChallengeReport()
{
return toChallengeReport;
}
public void setFromChallengeReport(ChallengeReport fromChallengeReport)
{
this.fromChallengeReport = fromChallengeReport;
}
public void setToChallengeReport(ChallengeReport toChallengeReport)
{
this.toChallengeReport = toChallengeReport;
}
}
Here where the Runnable is passed as argument:
// Record challenge
this.challengesManager.recordChallenge(whoSentRequest, whoConfirmedRequest,
new ChallengeReportDelegation()
{
#Override
public void run()
{
ChallengeReport fromReport = getFromChallengeReport();
ChallengeReport toReport = getToChallengeReport();
sendMessage(whoSentRequest, new Message(MessageType.CHALLENGE_REPORT, String.valueOf(fromReport.winStatus), String.valueOf(fromReport.challengeProgress), String.valueOf(fromReport.scoreGain)));
sendMessage(whoConfirmedRequest, new Message(MessageType.CHALLENGE_REPORT, String.valueOf(toReport.winStatus), String.valueOf(toReport.challengeProgress), String.valueOf(toReport.scoreGain)));
}
});
The receiving object store the ChallengeReportDelegation instance as completionOperation, wait for a timeout then execute this code.
private void complete()
{
stopTranslations();
int fromStatus;
int toStatus;
if (this.fromScore > this.toScore)
{
fromStatus = 1;
toStatus = -1;
}
else if (this.fromScore < this.toScore)
{
fromStatus = -1;
toStatus = 1;
}
else
{
fromStatus = 0;
toStatus = 0;
}
this.completionOperation.setFromChallengeReport(new ChallengeReport(this.from, fromStatus,this.fromTranslationsProgress, this.fromScore));
this.completionOperation.setToChallengeReport(new ChallengeReport(this.to, toStatus, this.toTranslationsProgress, this.toScore));
this.completionOperation.run();
}
The code above raises a NullPointerException at the execution of the last portion of code, in the run method.
[EDIT]
The NullPointerException exception is thrown because both getFromChallengeReport() and getToChallengeReport() (second portion of code) initially return null (when the Runnable is defined and passed as argument),
but they would return consistent values at invocation time run() (third portion of code)
[EDIT2]
I reproduced the situation in this simple code:
public class TestEvaluation
{
public static void main(String[] args) throws InterruptedException
{
Middle middle = new Middle();
middle.register(new Task() {
#Override
public void run() {
System.out.println("a is: " + getA());
System.out.println("b is: " + getB());
}
});
Thread.sleep(2000);
}
abstract static class Task implements Runnable
{
private int a = 0;
private int b = 0;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
#Override
abstract public void run();
}
static class Middle
{
private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1);
public void register(Task task)
{
Leaf leaf = new Leaf(new Task() {
#Override
public void run() {
System.out.println("Middle");
task.run();
}
});
pool.schedule(leaf, 1, TimeUnit.SECONDS);
}
}
static class Leaf implements Runnable
{
public Task task;
public Leaf(Task task)
{
this.task = task;
}
#Override
public void run()
{
task.setA(5);
task.setB(5);
System.out.println("Leaf");
task.run();
}
}
}
The behavior that i want to achieve is the printing of
Leaf
Middle
a is: 5
b is: 5
But this is what i get
Leaf
Middle
a is: 0
b is: 0
A very simple example. Lets create a runnable with a field.
public static void main (String[] args) {
var x = new Runnable(){
int a = 0;
int getA(){
return a;
}
void setA(int v){
a = v;
}
public void run(){
System.out.println("A : " + getA());
}
};
x.run();
x.setA(5);
x.run();
}
The first time it is 0, the second time 5, because getA is evaluated when run is called.
I found a working solution for this problem, perhaps trivial for those coming from functional programming.
Accordingly to the example in last edit ([EDIT2])
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
public class TestEvaluation
{
public static void main(String[] args) throws InterruptedException
{
Middle middle = new Middle();
middle.register(new Consumer<Values>() {
#Override
public void accept(Values values) {
System.out.println("a is: " + values.getA());
System.out.println("b is: " + values.getB());
}
});
Thread.sleep(2000);
}
static class Values
{
private int a = 0;
private int b = 0;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
}
static class Middle
{
private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1);
public void register(Consumer<Values> passed)
{
Consumer<Values> middleConsumer = new Consumer<Values>() {
#Override
public void accept(Values values) {
System.out.println("Middle");
passed.accept(values);
}
};
Leaf leaf = new Leaf(middleConsumer);
pool.schedule(leaf, 1, TimeUnit.SECONDS);
}
}
static class Leaf implements Runnable
{
public Consumer<Values> task;
public Leaf(Consumer<Values> task)
{
this.task = task;
}
#Override
public void run()
{
Values values = new Values();
values.setA(5);
values.setB(5);
System.out.println("Leaf");
task.accept(values);
}
}
}
This code produces the behavior i want.
Hope this will help someone.
Cheers!
If you want to immediately evaluate something. I'd suggest not using a Runnable at all. It sound like an anti-pattern, trying to pass code around when all you want is the value/invocation.
Furthermore, try to use a Callable or Supplier instead since you are clearly interested in returning some values from the sub-routines.
Related
I have a static variable and updating it's value in class. But when i access this variable from another class , it shows unupdated value.
CLASS A
public static int postID = 1;
public static String Creator()
{
String message = "POST id="+postID;
return message;
}
void updatePostID()
{
postID++; //this function is being called each 10 seconds
}
#Override
public void start() {
handler.post(show);
}
Handler handler = new Handler();
private final Runnable show = new Runnable(){
public void run(){
...
updatePostID();
handler.postDelayed(this, 10000);
}
};
CLASS B
String message = A.Creator(); //this always prints postID as 1 all time
I need a global variable that i can access from each class and update its value. Waiting for your help (I am using this with a Android Service)
this is a tested code .
public class A {
public static int id = 0;
public static int increment(){
return A.id++;
}
}
public class B {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println(A.increment());
}
}
}
class A
{
static int id=0;
//I am updating id in my function ,
{
id++;
}
}
public class StartingPoint {
public static void main(String... args){
A a = new A();
A b = new A();
System.out.println(A.id);
System.out.println(a.id);
}
}
You need to call work to execute id++;
class B {
public static void main(String... args){
A a = new A();
a.work(); // You need to call it to apply add operation
System.out.println(A.id); // Prints 1
}
}
And this is a sample class A:
class A {
static int id = 0;
public void work(){
id++;
}
}
Save class A in a file named A.java and class B in a file named B.java.
Then compile B. Since B creates an instance of class A, A will be compiled and you don't need to compile A separately-
javac B.java
After compilation, to execute/run-
java B
Sajal Dutta's answer explains it perfectly, but if you want to keep it ALL static (i.e. not create any objects of class A, you could modify the code slightly to this:
class A {
static int id = 0;
public static void work(){
id++;
}
}
Then:
class B {
public static void main(String[] args){
System.out.println(A.id);
A.work();
System.out.println(A.id);
}
}
This would produce:
0
1
Edit (with regard to your updated question)
Where are you specifying the update of the static int? From the code you've provided all you will do is print out the same int over and over as the method containing the increment process is never called.
Edit 2:
Try this:
Change:
handler.post(show);
to:
handler.postDelayed(show, 10000);
I have been trying to verify if the ThreadLocal members are indeed different in different threads.
This is my TestClass whose object I am sharing among multiple threads.
public class TestClass {
private static Set<Integer> setI;
private static ThreadLocal<Set<String>> setS;
public TestClass() {
Set<String> temp = new HashSet<String>();
for (int i=0; i<=4; i++) {
setI.add(i);
temp.add(Integer.toString(i));
}
setS.set(temp);
}
static {
setI = new HashSet<Integer>();
setS = new ThreadLocal<Set<String>>() {
protected Set<String> initialValue() {
return new HashSet<String>();
}
};
}
public static void addToIntegerSet(int i) {
synchronized(setI) {
setI.add(i);
}
}
public static void addToStringSet(String str) {
Set<String> sets = setS.get();
sets.add(str);
setS.set(sets);
}
}
the following is the class I use to test this out :-
package personal;
import java.util.*;
import personal.TestClass;
import java.lang.reflect.Field;
public class Test2 {
private static TestClass testObj;
private static Set<Set<String>> testStringSet;
private static Set<Set<Integer>> testIntegerSet;
static {
testObj = new TestClass();
testStringSet = new HashSet<Set<String>>();
testIntegerSet = new HashSet<Set<Integer>>();
}
private static void addToStringSet(Set<String> sets) {
synchronized(testStringSet) {
testStringSet.add(sets);
}
}
private static void addToIntegerSet(Set<Integer> sets) {
synchronized(testIntegerSet) {
testIntegerSet.add(sets);
}
}
private static int getTestIntegerSetSize() {
synchronized(testIntegerSet) {
return testIntegerSet.size();
}
}
private static int getTestStringSetSize() {
synchronized(testStringSet) {
return testStringSet.size();
}
}
private static class MyRunnable implements Runnable {
private TestClass tc;
private String name;
public MyRunnable(TestClass tc, int i) {
this.name = "Thread:- " + Integer.toString(i);
this.tc = tc;
}
#Override
public void run() {
try {
Field f1 = tc.getClass().getDeclaredField("setS");
Field f2 = tc.getClass().getDeclaredField("setI");
f1.setAccessible(true);
f2.setAccessible(true);
Set<String> v1 = (Set<String>)(((ThreadLocal<Set<String>>)(f1.get(tc))).get());
Set<Integer> v2 = (Set<Integer>) f2.get(tc);
addToIntegerSet(v2);
addToStringSet(v1);
} catch (Exception exp) {
System.out.println(exp);
}
}
}
public static void main(String[] args) {
for (int i=1; i<=2; i++) {
(new Thread (new MyRunnable(testObj,i))).start();
}
try {
Thread.sleep(5);
} catch (Exception exp) {
System.out.println(exp);
}
System.out.println(getTestStringSetSize());
System.out.println(getTestIntegerSetSize());
}
}
thus the 1st print statement should print out 2 and the second one should print out 1.
how ever the 1st print statement also prints out 1.
what is wrong ?
For a test class, I'd start with something much, much simpler. Just store a String or something in the ThreadLocal to start with, and avoid the reflection calls (setAccessible, etc.). Your issue is most likely in all of this extra code, and nothing due to the ThreadLocal itself.
I would like to implement a trampoline in java by returning a thunk whenever I hit a StackOverflowError. Are there any guarantees about the StackOverflowError, like, if the only thing I do after the StackOverflowError is creating objects on the heap and returning from functions, I will be fine?
If the above sounds vague, I have added some code for computing even/odd in a tail-recursive manner in continuation passing style, returning a delayed thunk whenever the stack flows over. The code works on my machine, but does Java guarantee that it will always work?
public class CPS {
public static class Thunk {
final Object r;
final Continuation c;
final boolean isDelayed;
public Object force() {
Thunk t = this;
while (t.isDelayed)
t = t.compute();
return t.r;
}
public Thunk compute() {
return this;
}
public Thunk(Object answer) {
isDelayed = false;
r = answer;
c = null;
}
public Thunk(Object intermediate, Continuation cont) {
r = intermediate;
c = cont;
isDelayed = true;
}
}
public static class Continuation {
public Thunk apply(Object result) {
return new Thunk(result);
}
}
public static Thunk even(final int n, final Continuation c) {
try {
if (n == 0) return c.apply(true);
else return odd(n-1, c);
} catch (StackOverflowError x) {
return new Thunk(n, c) {
public Thunk compute() {
return even(((Integer)n).intValue(), c);
}
};
}
}
public static Thunk odd(final int n, final Continuation c) {
try {
if (n == 0) return c.apply(false);
else return even(n-1, c);
} catch (StackOverflowError x) {
return new Thunk(n, c) {
public Thunk compute() {
return odd(((Integer)n).intValue(), c);
}
};
}
}
public static void main(String args[]) {
System.out.println(even(100001, new Continuation()).force());
}
}
I tried the following implementation possibilities:
A) With thunks (see code CPS below)
B) Without thunks as suggested by chris (see code CPS2 below)
C) With thunks with the stack overflow replaced by a depth check (see code CPS3 below)
In each case I checked if 100,000,000 is an even number. This check lasted
A) about 2 seconds
B) about 17 seconds
C) about 0.2 seconds
So returning from a long chain of functions is match faster than throwing an exception that unwinds that chain. Also, instead of waiting for a stack overflow, it is much faster to just record the recursion depth and unwind at depth 1000.
Code for CPS:
public class CPS {
public static class Thunk {
final Object r;
final boolean isDelayed;
public Object force() {
Thunk t = this;
while (t.isDelayed)
t = t.compute();
return t.r;
}
public Thunk compute() {
return this;
}
public Thunk(Object answer) {
isDelayed = false;
r = answer;
}
public Thunk() {
isDelayed = true;
r = null;
}
}
public static class Continuation {
public Thunk apply(Object result) {
return new Thunk(result);
}
}
public static Thunk even(final int n, final Continuation c) {
try {
if (n == 0) return c.apply(true);
else return odd(n-1, c);
} catch (StackOverflowError x) {
return new Thunk() {
public Thunk compute() {
return even(n, c);
}
};
}
}
public static Thunk odd(final int n, final Continuation c) {
try {
if (n == 0) return c.apply(false);
else return even(n-1, c);
} catch (StackOverflowError x) {
return new Thunk() {
public Thunk compute() {
return odd(n, c);
}
};
}
}
public static void main(String args[]) {
long time1 = System.currentTimeMillis();
Object b = even(100000000, new Continuation()).force();
long time2 = System.currentTimeMillis();
System.out.println("time = "+(time2-time1)+", result = "+b);
}
}
Code for CPS2:
public class CPS2 {
public abstract static class Unwind extends RuntimeException {
public abstract Object compute();
public Object force() {
Unwind w = this;
do {
try {
return w.compute();
} catch (Unwind unwind) {
w = unwind;
}
} while (true);
}
}
public static class Continuation {
public Object apply(Object result) {
return result;
}
}
public static Object even(final int n, final Continuation c) {
try {
if (n == 0) return c.apply(true);
else return odd(n-1, c);
} catch (StackOverflowError x) {
throw new Unwind() {
public Object compute() {
return even(n, c);
}
};
}
}
public static Object odd(final int n, final Continuation c) {
try {
if (n == 0) return c.apply(false);
else return even(n-1, c);
} catch (StackOverflowError x) {
return new Unwind() {
public Object compute() {
return odd(n, c);
}
};
}
}
public static void main(String args[]) {
long time1 = System.currentTimeMillis();
Unwind w = new Unwind() {
public Object compute() {
return even(100000000, new Continuation());
}
};
Object b = w.force();
long time2 = System.currentTimeMillis();
System.out.println("time = "+(time2-time1)+", result = "+b);
}
}
Code for CPS3:
public class CPS3 {
public static class Thunk {
final Object r;
final boolean isDelayed;
public Object force() {
Thunk t = this;
while (t.isDelayed)
t = t.compute();
return t.r;
}
public Thunk compute() {
return this;
}
public Thunk(Object answer) {
isDelayed = false;
r = answer;
}
public Thunk() {
isDelayed = true;
r = null;
}
}
public static class Continuation {
public Thunk apply(Object result) {
return new Thunk(result);
}
}
public static Thunk even(final int n, final Continuation c, final int depth) {
if (depth >= 1000) {
return new Thunk() {
public Thunk compute() {
return even(n, c, 0);
}
};
}
if (n == 0) return c.apply(true);
else return odd(n-1, c, depth+1);
}
public static Thunk odd(final int n, final Continuation c, final int depth) {
if (depth >= 1000) {
return new Thunk() {
public Thunk compute() {
return odd(n, c, 0);
}
};
}
if (n == 0) return c.apply(false);
else return even(n-1, c, depth+1);
}
public static void main(String args[]) {
long time1 = System.currentTimeMillis();
Object b = even(100000000, new Continuation(), 0).force();
long time2 = System.currentTimeMillis();
System.out.println("time = "+(time2-time1)+", result = "+b);
}
}
That's an interesting way to jump up the stack. It seems to work, but is probably slower than the usual way to implement this technique, which is to throw an exception that is caught $BIGNUM layers up the call stack.
package design.pattern.behavioral;
import design.pattern.behavioral.ChainOfResponsibility.*;
public class ChainOfResponsibility {
public static class Chain {
private Request[] requests = null;
private Handler[] handlers = null;
public Chain(Handler[] handlers, Request[] requests){
this.handlers = handlers;
this.requests = requests;
}
public void start() {
for(Request r : requests)
for (Handler h : handlers)
if(h.handle(r)) break;
}
}
public static class Request {
private int value;
public Request setValue(int value){
this.value = value;
return this;
}
public int getValue() {
return value;
}
}
public static class Handler<T> {
private Command<T> command = null;
public Handler(Command<T> command) {
this.command = command;
}
public boolean handle(T request) {
return command.execute(request);
}
}
public static abstract class Command<T>{
public abstract Boolean execute(T request);
}
}
class TestChainOfResponsibility {
public static void main(String[] args) {
new TestChainOfResponsibility().test();
}
private void test() {
new Chain(new Handler[]{ // chain of responsibility
new Handler<Request>(
new Command<Request>(){ // command
public Boolean execute(Request condition) {
boolean result = condition.getValue() >= 600;
if (result) System.out.println("You are rich: " + condition.getValue() + " (id: " + condition.hashCode() + ")");
return result;
}
}
),
new Handler<Request>(
new Command<Request>(){
public Boolean execute(Request condition) {
boolean result = condition.getValue() >= 100;
if(result) System.out.println("You are poor: " + condition.getValue() + " (id: " + condition.hashCode() + ")");
return result;
}
}
),
},
new Request[]{
new Request().setValue(600), // chaining method
new Request().setValue(100),
}
).start();
}
}
I don't think there is a meaningful answer to such a general question. Design patterns don't exist in isolation and don't have a "perfect form": they live in a context.
A pattern is a solution to a problem in a context.
So without knowing the context of your solution, there is not much we can say about it. What is the concrete problem you are trying to resolve with it? What forces are in play? What are your constraints? Do you have any problems / issues with the current solution? If you give more details about these, maybe we can give a better answer.
Lambda isn't very descriptive (to most developers). Is it something you are pulling in from functional language theory?
I'd probably just get rid of the 'controlling' class, and wire the individual handlers up to each other directly - use more of an IoC approach, basically.
Example (in C#, forgive me) per request...
public interface IIntMessage
{
void HandleMesasge(int i);
}
public class EvenPrinter : IIntMessage
{
private IIntMessage m_next;
public EvenPrinter(IIntMessage next)
{
m_next = next;
}
public void HandleMesasge(int i)
{
if(i % 2 == 0)
{
System.Console.WriteLine("Even!");
}
else
{
m_next.HandleMesasge(i);
}
}
}
public class OddPrinter : IIntMessage
{
private IIntMessage m_next;
public OddPrinter(IIntMessage next)
{
m_next = next;
}
public void HandleMesasge(int i)
{
if(i%2 == 1)
{
System.Console.WriteLine("Odd!");
}
else
{
m_next.HandleMesasge(i);
}
}
}
Note that we get rid of the "controlling" class altogether, and simply allow the request handlers to directly chain to each other, without having to go through an intermediary.
Also, I could probably extract out a 'base' chain-of-command request handler, removing some of the duplicate code.
This question came up in the course of my work programming; it's become irrelevant to the current task, but I'm still curious if anyone has an answer.
In Java 1.5 and up you can have a method signature using a variable number of arguments, with an ellipsis syntax:
public void run(Foo... foos) {
if (foos != null) {
for (Foo foo: foos) { //converted from array notation using autoboxing
foo.bar();
}
}
}
Suppose I want to do some operation on each foo in the foos list, and then delegate this call to some field on my object, preserving the same API. How can I do it? What I want is this:
public void run(Foo... foos) {
MyFoo[] myFoos = null;
if (foos != null) {
myFoos = new MyFoo[foos.length];
for (int i = 0; i < foos.length; i++) {
myFoos[i] = wrap(foos[i]);
}
}
run(myFoos);
}
public void run(MyFoo... myFoos) {
if (myFoos!= null) {
for (MyFoo myFoo: myFoos) { //converted from array notation using autoboxing
myFoo.bar();
}
}
}
This doesn't compile. How can I accomplish this (passing a variable number of MyFoo's to the run(MyFoo...) method)?
Is this what you want?
public class VarArgsTest {
public static class Foo {}
public static class MyFoo extends Foo {
public MyFoo(Foo foo) {}
}
public static void func(Foo... foos) {
MyFoo [] myfoos = new MyFoo[foos.length];
int i=0;
for (Foo foo : foos) {
myfoos[i++] = new MyFoo(foo);
}
func(myfoos);
}
public static void func(MyFoo... myfoos) {
for (MyFoo m : myfoos) {
System.out.println(m);
}
}
public static void main(String [] args) throws Exception {
func(new Foo(), new Foo(), new Foo());
}
}
I tried it and did NOT get a compile error. What is the actual error you are seeing? Here is the code I used. Perhaps i did something different:
public class MultipleArgs {
public static void main(String [] args){
run(new Foo("foo1"), new Foo("foo2"), new Foo("foo3"));
}
public static void run(Foo... foos){
MyFoo[] myFoos = null;
if (foos != null) {
myFoos = new MyFoo[foos.length];
for (int i = 0; i < foos.length; i++) {
myFoos[i] = wrap(foos[i]);
}
}
run(myFoos);
}
public static void run(MyFoo... myFoos){
if (myFoos!= null) {
for (MyFoo myFoo: myFoos) {
myFoo.bar();
}
}
}
private static class Foo {
public final String s;
public Foo(String s){
this.s = s;
}
#Override
public String toString(){
return s;
}
}
private static class MyFoo{
private final String s;
public MyFoo(String s){
this.s = s;
}
public void bar(){
System.out.println(s);
}
#Override
public String toString(){
return s;
}
}
private static MyFoo wrap(Foo foo){
return new MyFoo(foo.s);
}
}
This doesn't answer your question; it's incidental, but you don't need the null test. Here's proof:
public class VarargsTest extends TestCase {
public void testVarargs() throws Exception {
assertEquals(0, fn());
}
private int fn(String...strings) {
return strings.length;
}
}
If the method is called without any arguments, the varargs list is an empty array, not null.
I think the actual solution to your question would be to rename the second function.
use java reflections.