Implementing a recursive lambda function in Java - java

I don't know if the following thing is possible. I would like a Runnable's run() method to contain the Runnable itself, i.e.
reconnects = 3;
Runnable executeAfter = () -> {
if ( --reconnects < 0 ) {
println("%nStop using port %d.", this.port);
//...
} else { // try to reconnect
println("%nReconnecting...");
cmdRun = new CmdRun(command, executeAfter);
(new Thread(cmdRun)).start();
//...
}
};
Is something like this even possible? If so, how? (CmdRun's constructor is CmdRun(String command, Runnable executeAfter))

Is lambda a must here? If not, switching to older equivalent syntax should be simple:
An example:
public class TestLambda {
static int count = 0;
public static void main(String[] args) {
// lambda not going to work
//Runnable foo = () -> { if (count < 5) { call(foo); } };
// nor
//Runnable foo = () -> { if (count < 5) { call(this); } };
// using old way of anonymous inner class will work
Runnable foo = new Runnable() {
#Override public void run() {
if (count < 5) {
call(this);
}
}
};
foo.run();
}
public static void call(Runnable action) {
count++;
System.out.println("in call " + count);
action.run();
}
}

The easiest way is probably to put the content of your lambda in a method and use a method reference to define your Runnable.

The Runnable's run() can not contain a self reference as its illegal.
Im not exactly sure what you are trying to achieve but something like this should work :
class CmdRun implements Runnable {
final Object command;
final Runnable runnable;
final Runnable executeAfter = () -> {
if ( --reconnects < 0 ) {
System.out.println("%nStop using port %d." + port);
//...
} else { // try to reconnect
System.out.println("%nReconnecting...");
CmdRun cmdRun = new CmdRun(command);
(new Thread(cmdRun)).start();
//...
}
};
public CmdRun(Object command) {
this.command = command;
this.runnable = executeAfter;
}
#Override
public void run() {
runnable.run();
}
}

Short answer: No.
Long answer:
Your code will give you a syntax error. Why? The executeAfter used inside the lambda is not initialized; it is only initialized after the full body of the lambda definition.
For example, consider the below example.
int i;
sum(i, 5); // Syntax error!! Variable i is not initialized...
Your case is similar. Inside the lambda, executeAfter is not initialized. As stated above, it is only initialized after the full body of the lambda's definition.
One additional thing to node is that the variable reconnects must be a final in order to be used inside the lambda. If it is a final variable, then you cannot use the -- operator on it inside your if condition.

Actually if you don't mind to introduce a new interface (or if you require such functionality more often), you could use the following:
#FunctionalInterface
interface RecursiveRunnable extends Runnable {
default void run() {
run(this);
}
public void run(RecursiveRunnable runnable);
}
This will now allow you to recursively call the runnable, e.g.:
int maxTries = 3;
AtomicInteger counter = new AtomicInteger();
RecursiveRunnable foo = runnable -> {
if (counter.getAndIncrement() < maxTries) {
println("Reconnecting... %n");
runnable.run(); // same as: runnable.run(runnable)
} else {
println("Stop using port %d%n", port);
}
};

Related

How to create n threads and work with all of them

Im trying to create a given number of threads and treat them at the same time to make a "race" program. The threads are created but im doing something wrong because any of the threads prints "Hi".
public class Principal implements Runnable{
public static void main(String[] args) {
int howManyThreads = 3;
Thread thread[];
thread = new Thread[howManyThreads];
for ( int i=0; i < thread.length; i++ ){
thread[i]= new Thread();
thread[i].setName("Thread - " + i);
}
for ( int i=0; i < thread.length; ++i){
thread[i].start();
System.out.println(thread[i].getName() + " - " + thread[i].getState());
}
}
public void run() {
System.out.println("Hi");
}
}
The default constructor for the Thread class creates a thread that does nothing. You're calling that default constructor here: thread[i] = new Thread();
If you want the thread to actually do something, then you must provide a Runnable instance as an argument to the Thread constructor. There are a couple of ways to do that. The newest, most concise way is to use a lambda expression:
thread[i] = new Thread(() -> {
System.out.println("Hi");
});
The Runnable interface is an #FunctionalInterface. Since the compiler knows that the Thread(...) constructor wants an object of that type, it infers that that's what the lambda should create, and the body of the lambda becomes the run() method of the new object.
Another, older way to provide a Runnable object is to use an anonymous inner class expression. The syntax is a little more cumbersome because you have to explicitly say what interface the new class should implement, and you have to explicitly declare the run() method:
thread[i] = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Hi");
}
});
The oldest way, still even more verbose, is to explicitly declare a named class:
class MyRunnable implements Runnable {
#Override
public void run() {
System.out.println("Hi");
}
};
public class Principal /*does not need to implement Runnable*/ {
...
thread[i] = new Thread(new MyRunnable());
...
}
You might ask, why did I remove implements Runnable from the Principal class, and create a whole new class?
I did it because, I've read this book: https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/

Best way to store a run count for a recursive Runnable that is run by a Handler?

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (counter <= 200) {
doThing();
counter++;
handler.postDelayed(this, 50);
}
}
}, 0);
In the above code I have a Handler running a Runnable. My issue is that since the counter object is inside a Runnable it will need to be declared final.
What is the best way to handle this incrementing value?
Currently I am simply using a counter object but I feel it should be easier:
class Counter {
int count;
Counter() {
count = 0;
}
public void addOne() {
count++;
}
}
There are already classes that you could use instead, like AtomicInteger, or similar, but slightly different LongAdder.
You instantiate an object of that class, and then you can simply invoke various methods that will change the internal value of that object.
These classes also provide the required thread safety. Without that property, it is rather unlikely that your counter will count up correctly!
Rather than using postDelayed(), you could use sendMessageDelayed(). You could send a Message that indicates that you want to run that runnable, and then use the arg1 field to store the current count.
private static final int WHAT_DO_WORK = 1;
final Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (msg.what == WHAT_DO_WORK) {
doWork(msg.arg1);
}
}
};
private void doWork(int counter) {
if (counter <= 200) {
doThing();
int arg1 = count + 1;
Message message = Message.obtain(handler, WHAT_DO_WORK, arg1, 0);
handler.sendMessageDelayed(message, 50);
}
}

Unable to understand sync

Hey I am trying to make 10 threads in a synchronized manner and I came up with the code below however I am not able to understand a part of it as mentioned below. I am still really new to java, I tried looking up synchronized threading from
Here but still I am clueless.
class question3 {
public static void main(String arg[]) throws Exception {
for (int i = 0; i < 11; i++) {
data di = new data();
System.out.println(di.count);
}
}
}
class item {
static int count = 0;
}
class data extends item implements Runnable {
item d = this;
Thread t;
data() {
t = new Thread(this);
t.start();
}
public void run() {
d = syn.increment(d);
}
}
class syn {
synchronized static item increment(item i) {
i.count++;
return (i);
}
}
I am not sure what this part of code does?
public void run() {
d = syn.increment(d);
}
}
class syn {
synchronized static item increment(item i) {
i.count++;
return (i);
}
}
the run function is used when starting the thread, this is a must function you need to override when implement Runnable. When calling Thread.start(), the run function will be called.
The class syn contains a synchronized method, it is simply mean that only one thread can access it each time, thus make the incerment function thread safe.
object d has a static variable count meaning all instances of item class (and data ) share the same count, so all threads increment the same variable
the line d = syn.increment(d); is basically count++ but in a thread safe way

Passing variable into methods (Java)

I'm new to Java, and I have a problem. I've copied some code off a tutorial for Android, and now I want to pass an integer variable into the method run(), so I can increment it for each loop and then catch it outside the background Thread. How would I do that?
int gg= 0;
Thread background = new Thread(new Runnable() {
public void run() {
try {
while (pBarDialog.getProgress() <= 100) {
Thread.sleep(100);
gg++; // the increment here
progressHandler.sendMessage(progressHandler
.obtainMessage());
}
if (pBarDialog.getProgress() == 100) {
pBarDialog.dismiss();
}
} catch (java.lang.InterruptedException e) {
// if something fails do something smart
}
}
});
//catch gg here
You can't specify argument to the run() method. You may declare int variable as field and use it in inner classes.
public class TestActivity extends Activity
{
private volatile int no;
.....
}
EDIT: (Suggestion from #alf) You can use volatile modifier with field so changed value can be seen immediately by all other threads.
Have your own class and pass the counter using its constructor, I haven't tried that, but I would start with something like that:
class MyThread implements Runnable {
private volatile int counter;
public MyThread( int counter ) {
this.counter = counter;
}
public void run() {
...
}
public getCounter() {
return counter;
}
}
MyThread mt = new MyThread( 10 );
Thread t = new Thread( mt );
t.start();
// after some time
t.getCounter();
private volatile int gg;
public void myMethod() {
Thread background = new Thread(new Runnable() {
#Override
public void run() {
try {
while (pBarDialog.getProgress() <= 100) {
Thread.sleep(100);
gg++; // the increment here
progressHandler.sendMessage(progressHandler.obtainMessage());
}
if (pBarDialog.getProgress() == 100) {
pBarDialog.dismiss();
}
} catch (java.lang.InterruptedException e) {
// if something fails do something smart
}
}
});
System.out.println(gg);
}
If I were you, I'd be looking into AtomicInteger, namely the incrementAndGet() method.
Making gg a field will indeed give the thread access to gg, and volatile will make the changes visible, but since your intentions are not clear, I cannot be sure that you don't have other threads incrementing the same value: you don't have atomicity, so as soon as you have more than one thread doing gg++, you're likely to get wrong results.

How can I pass a parameter to a Java Thread?

Can anyone suggest to me how I can pass a parameter to a thread?
Also, how does it work for anonymous classes?
You need to pass the parameter in the constructor to the Runnable object:
public class MyRunnable implements Runnable {
public MyRunnable(Object parameter) {
// store parameter for later user
}
public void run() {
}
}
and invoke it thus:
Runnable r = new MyRunnable(param_value);
new Thread(r).start();
For Anonymous classes:
In response to question edits here is how it works for Anonymous classes
final X parameter = ...; // the final is important
Thread t = new Thread(new Runnable() {
p = parameter;
public void run() {
...
};
t.start();
Named classes:
You have a class that extends Thread (or implements Runnable) and a constructor with the parameters you'd like to pass. Then, when you create the new thread, you have to pass in the arguments, and then start the thread, something like this:
Thread t = new MyThread(args...);
t.start();
Runnable is a much better solution than Thread BTW. So I'd prefer:
public class MyRunnable implements Runnable {
private X parameter;
public MyRunnable(X parameter) {
this.parameter = parameter;
}
public void run() {
}
}
Thread t = new Thread(new MyRunnable(parameter));
t.start();
This answer is basically the same as this similar question: How to pass parameters to a Thread object
via constructor of a Runnable or Thread class
class MyThread extends Thread {
private String to;
public MyThread(String to) {
this.to = to;
}
#Override
public void run() {
System.out.println("hello " + to);
}
}
public static void main(String[] args) {
new MyThread("world!").start();
}
This answer comes very late, but maybe someone will find it useful. It is about how to pass a parameter(s) to a Runnable without even declaring named class (handy for inliners):
String someValue = "Just a demo, really...";
new Thread(new Runnable() {
private String myParam;
public Runnable init(String myParam) {
this.myParam = myParam;
return this;
}
#Override
public void run() {
System.out.println("This is called from another thread.");
System.out.println(this.myParam);
}
}.init(someValue)).start();
Of course you can postpone execution of start to some more convenient or appropriate moment. And it is up to you what will be the signature of init method (so it may take more and/or different arguments) and of course even its name, but basically you get an idea.
In fact there is also another way of passing a parameter to an anonymous class, with the use of the initializer blocks. Consider this:
String someValue = "Another demo, no serious thing...";
int anotherValue = 42;
new Thread(new Runnable() {
private String myParam;
private int myOtherParam;
// instance initializer
{
this.myParam = someValue;
this.myOtherParam = anotherValue;
}
#Override
public void run() {
System.out.println("This comes from another thread.");
System.out.println(this.myParam + ", " + this.myOtherParam);
}
}).start();
So all happens inside of the initializer block.
When you create a thread, you need an instance of Runnable. The easiest way to pass in a parameter would be to pass it in as an argument to the constructor:
public class MyRunnable implements Runnable {
private volatile String myParam;
public MyRunnable(String myParam){
this.myParam = myParam;
...
}
public void run(){
// do something with myParam here
...
}
}
MyRunnable myRunnable = new myRunnable("Hello World");
new Thread(myRunnable).start();
If you then want to change the parameter while the thread is running, you can simply add a setter method to your runnable class:
public void setMyParam(String value){
this.myParam = value;
}
Once you have this, you can change the value of the parameter by calling like this:
myRunnable.setMyParam("Goodbye World");
Of course, if you want to trigger an action when the parameter is changed, you will have to use locks, which makes things considerably more complex.
I know that I'm a few years late, but I came across this issue and took an unorthodox approach. I wanted to do it without making a new class, so this is what I came up with:
int x = 0;
new Thread((new Runnable() {
int x;
public void run() {
// stuff with x and whatever else you want
}
public Runnable pass(int x) {
this.x = x;
return this;
}
}).pass(x)).start();
You can either extend the Thread class or the Runnable class and provide parameters as you want. There are simple examples in the docs. I'll port them here:
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
PrimeThread p = new PrimeThread(143);
p.start();
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
To create a thread you normally create your own implementation of Runnable. Pass the parameters to the thread in the constructor of this class.
class MyThread implements Runnable{
private int a;
private String b;
private double c;
public MyThread(int a, String b, double c){
this.a = a;
this.b = b;
this.c = c;
}
public void run(){
doSomething(a, b, c);
}
}
Either write a class that implements Runnable, and pass whatever you need in a suitably defined constructor, or write a class that extends Thread with a suitably defined constructor that calls super() with appropriate parameters.
In Java 8 you can use lambda expressions with the Concurrency API & the ExecutorService as a higher level replacement for working with threads directly:
newCachedThreadPool() Creates a thread pool that creates new threads
as needed, but will reuse previously constructed threads when they are
available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks.
private static final ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {
myFunction(myParam1, myParam2);
});
See also executors javadocs.
As of Java 8, you can use a lambda to capture parameters that are effectively final. For example:
final String param1 = "First param";
final int param2 = 2;
new Thread(() -> {
// Do whatever you want here: param1 and param2 are in-scope!
System.out.println(param1);
System.out.println(param2);
}).start();
Parameter passing via the start() and run() methods:
// Tester
public static void main(String... args) throws Exception {
ThreadType2 t = new ThreadType2(new RunnableType2(){
public void run(Object object) {
System.out.println("Parameter="+object);
}});
t.start("the parameter");
}
// New class 1 of 2
public class ThreadType2 {
final private Thread thread;
private Object objectIn = null;
ThreadType2(final RunnableType2 runnableType2) {
thread = new Thread(new Runnable() {
public void run() {
runnableType2.run(objectIn);
}});
}
public void start(final Object object) {
this.objectIn = object;
thread.start();
}
// If you want to do things like setDaemon(true);
public Thread getThread() {
return thread;
}
}
// New class 2 of 2
public interface RunnableType2 {
public void run(Object object);
}
You can derive a class from Runnable, and during the construction (say) pass the parameter in.
Then launch it using Thread.start(Runnable r);
If you mean whilst the thread is running, then simply hold a reference to your derived object in the calling thread, and call the appropriate setter methods (synchronising where appropriate)
There is a simple way of passing parameters into runnables.
Code:
public void Function(final type variable) {
Runnable runnable = new Runnable() {
public void run() {
//Code adding here...
}
};
new Thread(runnable).start();
}
No you can't pass parameters to the run() method. The signature tells you that (it has no parameters). Probably the easiest way to do this would be to use a purpose-built object that takes a parameter in the constructor and stores it in a final variable:
public class WorkingTask implements Runnable
{
private final Object toWorkWith;
public WorkingTask(Object workOnMe)
{
toWorkWith = workOnMe;
}
public void run()
{
//do work
}
}
//...
Thread t = new Thread(new WorkingTask(theData));
t.start();
Once you do that - you have to be careful of the data integrity of the object you pass into the 'WorkingTask'. The data will now exist in two different threads so you have to make sure it is Thread Safe.
One further option; this approach lets you use the Runnable item like an asynchronous function call. If your task does not need to return a result, e.g. it just performs some action you don't need to worry about how you pass back an "outcome".
This pattern lets you reuse an item, where you need some kind of internal state. When not passing parameter(s) in the constructor care is needed to mediate the programs access to parameters. You may need more checks if your use-case involves different callers, etc.
public class MyRunnable implements Runnable
{
private final Boolean PARAMETER_LOCK = false;
private X parameter;
public MyRunnable(X parameter) {
this.parameter = parameter;
}
public void setParameter( final X newParameter ){
boolean done = false;
synchronize( PARAMETER_LOCK )
{
if( null == parameter )
{
parameter = newParameter;
done = true;
}
}
if( ! done )
{
throw new RuntimeException("MyRunnable - Parameter not cleared." );
}
}
public void clearParameter(){
synchronize( PARAMETER_LOCK )
{
parameter = null;
}
}
public void run() {
X localParameter;
synchronize( PARAMETER_LOCK )
{
localParameter = parameter;
}
if( null != localParameter )
{
clearParameter(); //-- could clear now, or later, or not at all ...
doSomeStuff( localParameter );
}
}
}
Thread t = new Thread(new MyRunnable(parameter));
t.start();
If you need a result of processing, you will also need to coordinate completion of MyRunnable when the sub-task finishes. You could pass a call back or just wait on the Thread 't', etc.
Specially for Android
For callback purposes I usually implement my own generic Runnable with input parameter(s):
public interface Runnable<TResult> {
void run(TResult result);
}
Usage is simple:
myManager.doCallbackOperation(new Runnable<MyResult>() {
#Override
public void run(MyResult result) {
// do something with the result
}
});
In manager:
public void doCallbackOperation(Runnable<MyResult> runnable) {
new AsyncTask<Void, Void, MyResult>() {
#Override
protected MyResult doInBackground(Void... params) {
// do background operation
return new MyResult(); // return resulting object
}
#Override
protected void onPostExecute(MyResult result) {
// execute runnable passing the result when operation has finished
runnable.run(result);
}
}.execute();
}
Create a local variable in your class that extends Thread or implements Runnable.
public class Extractor extends Thread {
public String webpage = "";
public Extractor(String w){
webpage = w;
}
public void setWebpage(String l){
webpage = l;
}
#Override
public void run() {// l is link
System.out.println(webpage);
}
public String toString(){
return "Page: "+webpage;
}}
This way, you can pass a variable when you run it.
Extractor e = new Extractor("www.google.com");
e.start();
The output:
"www.google.com"
First I want to point out that other answers are true.
However, using the parameter in the constructor may not be the best idea for all of you.
In many scenarios you will want to use "Anonymous Inner Class", and override the run() method, because defining specific class for every use is painful.
(new MyRunnable(){...})
And at the time you create that Runnable, the parameter may not be available to you to pass it in the constructor. If for example, you pass this object to a method, that will perform some work in separate thread and then call your runnable, applying the result from that work to it.
In that case, using a method like this one:
public MyRunnable withParameter(Object parameter), may turn out to be far more useful choice.
I do not claim that this is the best solution to the problem, but it will get the job done.

Categories