Function as a function parameter in Java - java

I have a class, with Thread as superclass, I pass a function as a parameter and this class just execute that function. This class uses it to create threads, so I can execute any function in a thread without having to create a different class.
public class ThreadEjecucionLambda extends Thread {
Runnable funcion;
public ThreadEjecucionLambda(Runnable funcion)
{
this.funcion=funcion;
}
public void run()
{
funcion.run();
}
}
Now, to create several threads of a same method I use a 'for' block, for example:
for(Computer computer: Persistencia.getListComputers())
{
ThreadEjecucionLambda hilolambda=new ThreadEjecucionLambda(()->logica.EnciendeMonitor(computer.getNombrePC()));
hilolambda.run();
}
What I want to achieve is to generalice the previous 'for' so that I can execute a method,to which I will pass ,as parameters, (following the example) a list of 'Computers' and a function. This method will execute the 'for' block and will create a thread for each 'Computer, so I will pass as a parameter the previous function to the thread and that function will have, as a parameter, the 'Computer'.
What I want to get is something like this (WARNING: IT'S WRONG):
public void EjecutaHilosLambdaSegundo(ArrayList<Computer> listapcs,Runnable funcion)
{
for(Computer computer: listapcs)
{
ThreadEjecucionLambda hilolambda=new ThreadEjecucionLambda(funcion(computer));
hilolambda.run();
}
}
I hope I have explained myself well because it's a very confusing problem.

Thread already has a constructor taking a Runnable as argument, and executing it when you start it, so your subclass is useless and confusing. Not only that, but you never actually start any thread. So you could just run the Runnable directly, without creating any Thread or ThreadEjecucionLambda.
If I understand correctly, you want to execute the same function, taking a Computer as argument, on a list of Computers.
You don't need a Thread to do that. All you need is a Consumer<Computer>:
public consumeAllComputers(List<Computer> computers, Consumer<? super Computer> function) {
computers.forEach(function);
}
But, as you see, this method is useless, since you could just call forEach on the List directly.
So, suppose you want to print the name of each computer in a list, you would use
computers.forEach(computer -> System.out.println(computer.getName());
Don't reinvent the wheel!

For the synchronous solution, look at #JB Nizet answer.
Asynchronous solution
First, your ThreadEjecucionLambda class is not creating thread, because to start a new thread, you need to call the start() method of Thread.
public class ThreadEjecucionLambda extends Thread {
Runnable funcion;
public ThreadEjecucionLambda(Runnable funcion)
{
super(funcion);
this.funcion = funcion;
}
public void run()
{
super.start();
}
}
Second, this class is meaningless! Thread is already working that way.
Third, Runnable as is does not accept argument. What you actually need to do is create your own Runnable that takes a Computer as an argument.
public class MyRunnable implements Runnable {
Computer computer;
public MyRunnable(Computer computer)
{
this.computer = computer;
}
#Override
public void run()
{
// Do what you want cause a pirate is-
// Erm do what you want with your computer object
}
}
And then use it for your above method.
public void EjecutaHilosLambdaSegundo(ArrayList<Computer> listapcs, MyRunnable myRunnable)
{
for(Computer computer: listapcs)
{
Thread myThread = new Thread(myRunnable);
myThread.start();
}
}

Related

Calling a method of a class which extends Thread, from another class

I know this is a bit naive question but I want to understand the basic working principle behind multi-threading in java. Consider the following code and say A is executed in Main thread and it starts execution of another worker thread ,defined in class B. I want to know that can B.func1 called from A and run method of B, be executed in parallel or not?
public class A {
public static void main(String[] args) {
B obj = new B();
obj.start();
obj.func1();
}
}
public class B extends Thread {
public B() {
//constructor
}
public void run() {
while(true) {
//do somethings
}
}
public void func1() {
//do someotherthings
}
}
There is no magic behind a method call. If you call method from a thread, it is called in exactly the same thread. So since obj.func1() is called from main, it will be run in the main thread. It doesn't matter which class it belongs to or whether or not it extends Thread.
The new thread starts by executing run. Everything called from run and so on will be executed in parallel to main.
It's important to understand the difference between a thread and a Thread.
A thread is an independent execution of your code. Often when we talk about how some method or another works we say things like, "It tests the variable x, and if x is less than zero it calls the foobar method..."
Ok, but what is the "it" in that sentence? It is not the method. Methods don't do anything. A method is just a list of instructions, like the list of chores that somebody left for their housemate to perform. The list doesn't do the chores, it's the housemate that does the work (or so we might hope).
The "it" is a thread. Threads are entities in the operating system that execute methods (i.e., they do the chores).
A Thread, on the other hand, is a Java object that your program can use to create and manage new threads. Your program creates a new Thread object by doing:
thread t = new Thread(...);
[Oops! See what I just did? It's not your program, that does the work, it's your program's main thread, or maybe some other thread in your program. It's an easy thing to forget!]
Anyway, it subsequently creates the new thread by calling t.start();
Once you understand all that, then Sergey Tachenov's answer becomes obvious: Calling the methods of a Thread object really is no different from calling methods of any other kind of object.
There are multiple issues with your code. I have corrected them and added one more statement to print Thread Name in func1().
Working code:
public class A {
public static void main(String args[]){
B obj = new B();
obj.start();
obj.func1();
}
}
class B extends Thread{
public B (){
//constructor
}
public void run(){
while(true){
//do somethings
}
}
public void func1 (){
//do someotherthings
System.out.println("Thread name="+Thread.currentThread().getName());
}
}
output:
Thread name=main
Since you are directly calling func1() from main method (A.java) , you will get Thread name = main in output.
If you add same print statement run() method, you will get output as : Thread name=Thread-0

java threading method within object with return value

I am pretty new to using multithreading, but I want to invoke a method asynchronously (in a separate Thread) rather than invoking it synchronously. The basic idea is that I'm creating a socket server with an object in memory, so for each client I will have to run something like object.getStuff() asynchronously.
The two constructs I found were:
having the class implement Runnable and threading this and
declaring a runnable class within a method.
Additionally this method needs a return value- will it be necessary to use Executor and Callable to achieve this? Could someone point me in the right direction for implementing this?
I have tried implement option 2, but this doesn't appear to be processing concurrently:
public class Test {
private ExecutorService exec = Executors.newFixedThreadPool(10);
public Thing getStuff(){
class Getter implements Callable<Thing>{
public Thing call(){
//do collection stuff
return Thing;
}
}
Callable<Thing> callable = new Getter();
Future<Thing> future = exec.submit(callable);
return future.get();
}
}
I am instantiating a single test object for the server and calling getStuff() for each client connection.
Threading Tutorial
The Java tutorial on concurrency has a good section on this. It's at https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html. Essentially, you can either implement Runnable or Callable, or inherit from Thread.
Subclassing Thread
You can write a class, including an anonymous inner class, that extends Thread. Instantiate it, then invoke the start() method.
public class MyThread extends Thread {
public void run() {
System.out.println("This is a thread");
}
public static void main(String[] args) {
MyThread m = new MyThread();
m.start();
}
}
Implementing Runnable
You can write a class that implements Runnable, then wrap an instance in a Thread and invoke start(). Very much like the previous.
public class MyRunnable implements Runnable {
public void run() {
System.out.println("This is a thread");
}
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
(new Thread(r)).start();
}
}
Return Value
Runnable doesn't allow for return values. If you need that, you need to implement Callable instead. Callable looks a lot like Runnable, except you override the call() method instead of the run() method, and you need to give it to an ExecutorService.
public class MyCallable implements Callable<Integer> {
public Integer call() {
System.out.println("A thread using Callable<Integer>");
return 42;
}
public static void main(String[] args) {
MyCallable c = new MyCallable();
Future<Integer> f = Executors.newSingleThreadExecutor().submit(c));
System.out.println("The thread returned: " +
f.get());
}
}
The two constructs I found were 1) having the class implement Runnable and threading 'this' and 2) declaring a runnable class within a method.
Option (2) probably is better. Most programs would be improved if they had more classes, not fewer. Each named entity in a program—each package, class, method, whatever—should have just one responsibility. In your option (1), you are asking the class to do two things.
For your option (2), you don't actually have to declare a whole class. You can either use an anonymous inner class, or if you can go with Java8 all the way, you can use a lambda expression. Google for either one to learn more.
Additionally this method needs a return value.
The classic way, is for the Runnable object to return the value through one of its own fields before the thread terminates. Then the parent thread, can examine the object and get the return value afterward.
Will it be necessary to use Executor and Callable to achieve this?
Necessary? A lot of people think that ExecutorService is a Good Thing.
Sounds like you are creating a server that serves multiple clients. Do these clients continually connect and disconnect? The advantage of using a thread pool (i.e., ThreadPoolExecutor) is that it saves your program from continually creating and destroying threads (e.g., every time a client connects/disconnects). Creating and destroying threads is expensive. If you have a lot of clients connecting and disconnecting, then using a thread pool could make a big difference in the performance of your server.
Creating and managing threads by yourself is generally bad approach.
As you already pointed - use Executors utility class to create executor and submit Callables to it.
public class RunWResult implements Runable{
private volatile ResultType var;
//the thread method
public void run(){
...
//generate a result and save it to var
var = someResult();
//notify waiting threads that a result has been generated
synchronized(this){
notify();
}
}
public ResultType runWithResult(){
//run the thread generating a result
Thread t = new Thread(this);
t.start();
//wait for t to create a result
try{
wait();
}catch(InterruptedException e){}
//return the result
return var;
}
}

What the use of Thread constructor with string param?

Looking at the Thread constructors, I see there is one that takes single string parameter. I have the below code, which is kind of useless. I would like to know, how to make a fruitful use of this constructor and make something actually run
public class ThreadTest {
public static void main(String[] args) {
Thread t = new Thread("abc");
t.start();
System.out.println("Complete");
}
}
Or Is it not supposed to be used the way I demonstrated above?
I perfectly know how to write multiple threads and execute :), I am just trying to understand the correct use of this constructor? Should it only be used by calling super(name) by extending Thread and not by the way I am using it above.
The thread class in itself doesn't do all that much. You have to extend it or construct it around a runnable to make it perform a task when run. From the doc:
start(): "Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread."
run(): "If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns."
Therefore constructing a new thread in your fashion and starting it does nothing. One use of the Thread(String) constructor is in subclasses:
public class Worker extends Thread{
public Worker(int numb){
super("worker-"+numb);
}
#Override
public void run(){
//Stuff this thread actually does when run
//....
for(int i = 0; i < 10; i++)
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
To answer your second question in the comments, this is how you would write code that's executed in parallel. Consider the above class plus this main method:
public static void main(String[] args){
Worker w1 = new Worker(1);
Worker w2 = new Worker(2);
w1.start();
w2.start();
}
The run methods of w1 and w2 will be executed in parallel. The order of the print statements will vary between executions of the main method.
This particular constructor is used to specify the 'name' of a thread, which can later be used to distinguish between instances of a specific thread type.
From the official Java API documentation;
Thread
public Thread(String name)
Allocates a new Thread object. This
constructor has the same effect as Thread (null, null, name).
Parameters: name - the name of the new thread
Once you have allocated a Thread a name, you can call the getName() method on the Thread instance to return the name it was given when it was created. This can be useful for debugging or for distinguishing between instances of of the same Thread subclass type.
Extra Reading:
Official Guide - Defining and Starting a Thread
If you simply call this constructor you get a Thread which does nothing. Why? Look at the source code of java.lang.Thread. It has a private Runnable target; class variable. When you call this constructor, the target variable remains set to null (because this constructor simply sets the Thread's name).
Also, the run() method of java.lang.Thread looks like this:
public void run() {
if (target != null) {
target.run();
}
}
So it means that this run() method will do nothing as target is null.
In order to create/start a Thread which really does something useful read here:
The Java tutorial - how to run a thread?

Java new Thread using this - Any reason if it is good / bad?

Just a quick question look at the code below, is there any reason why wouldn't do this or is it fine?
public class MyClass implements Runnable, MyClassInterface {
Thread threader;
void start() {
threader = new Thread(this);
threader.start();
}
#Override
public void run() {
Thread current = Thread.getCurrentThread();
while (threader = current) {
..
}
}
}
The original logic was not to expose that fact it runs in a separate thread to the caller
who creates a "MyClass" but then there are doubts if that is a good thing or bad.
Can anyone see any good reason not to do it or is it acceptable. It can be expected that MyClass.start() maybe called a few times.
EDIT: Updated the code to show it is implementing Runnable and one other interface, the interface is used by client code, the actual implementation may run in a separate thread, same thread or any other way. The idea was to abstract that away from the client, as the client is simply an object that "MyClass" will notify and is not aware (currently) of the Runnable interface it implements.
Perhaps that abstraction is not needed and client should have more control?
EDIT: The start() was simply to tell the object it is ready to start receiving notifications rather than start a thread.
Have a look at this: http://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
In my opinion, it is a bad design, because you are breaking encapsulation by implementing an interface (Runnable) and by providing a public method (run) that are of no use of the consumer of the class.
You can start a thread from the start method without inhering from Runnable:
public class MyClass {
private Thread thread;
public void start() {
thread = new Thread(this::doWork); // Java 8 method reference
thread.start();
}
private void doWork() {
// ...
}
}
If you can't use method references from Java 8, replace this::doWork with:
new Runnable() { public void run() { doWork(); } }

Threads; Creating a separate thread to periodically do something

As an addition to my current application, I need to create a separate thread which will periodically do some processing
I've create a new class to do all this, and this class will be loaded on startup of my application.
This is what I have so far :
public class PeriodicChecker extends Thread
{
static
{
Thread t = new Thread(new PeriodicChecker());
while(true)
{
t.run();
try
{
Thread.sleep(5000l);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
/**
* Private constructor to prevent instantiation
*/
private PeriodicChecker()
{
}
#Override
public void run()
{
System.out.println("Thread is doing something");
// Actual business logic here, that is repeated
}
}
I want to make constructor private to prevent other people from attempting to instantiate this class accidentally. How can I achieve this?
Also, is there anything bad about my implementation of such requirements? I'm only creating one thread which will run then sleep, have I missed anything obvious? I haven't worked with threads before
Java offers ScheduledExecutorService to schedule and run periodic tasks or tasks with delay. It should provide all the features you need. Timer is another class that offers similar functionalities, but I would recommend the ScheduledExecutorService over Timer for its flexibility of configuration and better error management.
You have some conceptual erros in your code... for example:
You should call start() and not run(), because you are running the method sequentially and not simultaneously.
You can call start() only once, not once in each loop iteration. After that, the thread is in state TERMINATED, you should create a new thread to run it again
You should not create the thread in the static block, it is a bad practice, and maybe the Thread is running before you want it to run.
You should read some examples about thread, it is a little difficult to unserstand at the beginning, and you can have undesired effects very easily.
Here is a little example, that may do something similar to that you want:
public class PeriodicChecker extends Thread
{
#Override
public void run()
{
while(true) {
System.out.println("Thread is doing something");
Thread.sleep(5000);
}
}
}
public OtherClass {
public static void main(String args[]) {
Thread t = new PeriodicChecker();
t.start();
}
}
If you want that none can create a new Thread, you could create a singleton, so you will be sure that none is creating more threads.
I'd recommend you to consider Timer class - it provides functionality for periodic tasks execution.
Also you may take a look at "Timer & TimerTask versus Thread + sleep in Java" question discussion - there you can find some arguments and examples.
First of all to answer your specific question, you have already achieved your objective. You have declared your constructor to be private meaning no external class can call it like new PeriodicChecker().
Looking at your code however, there are a number of other problems:
Firstly, you are creating an instance of your class within its own static constructor. The purpose of a static constructor is to initialise any static state that your class may have, which instances of your class may then depend on. By creating an instance of the class within the static constructor, all of these guarantees go out the window.
Secondly, I don't think your thread is going to behave in the way you expect it to behave, primarily because you don't actually start another thread :). If you intend to start a new thread, you need to call the start() method on that thread object. Calling run() as you do does not actually create a new thread, but simply runs the run() method in the current thread.
Nowadays when you want to create a new thread to do something, the reccomended way of achieving this is to not extend Thread, but instead implement the Runnable interface. This allows you to decouple the mechanism of the thread, from the behaviour you intend to run.
Based on your requirements, I would suggest doing away with a top-level class like this, and instead create either a private inner class within your application start-up code, or even go for an anonymous inner class:
public class Main {
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
while(true) {
System.out.println("Thread is doing something");
Thread.sleep(5000);
}
}
}).start();
}
}
It is almost never right to extend Thread. If you ever find yourself doing this, step back, take a look and ask yourself if you really need to change the way the Thread class works.
Almost all occurances where I see extends Thread the job would be better done implementing the Runnable interface or using some form of Timer.

Categories