Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to take an argument in a callable method?

I have created a piece of code which takes an IP address (from main method in another class) and then loops through a range of IP addresses pinging each one as it goes. I have a GUI front end on this and it was crashing (hence why I've done the multithreading. My problem is I can no longer take the IP address as an argument in my ping code as its callable. I've searched all over for this and cant seem to find a way to get round this. Is there a way for a callable method to take arguments? If not is there any other way to accomplish what I'm trying to do?

sample of my code:

public class doPing implements Callable<String>{  public String call() throws Exception{      String pingOutput = null;      //gets IP address and places into new IP object     InetAddress IPAddress = InetAddress.getByName(IPtoPing);     //finds if IP is reachable or not. a timeout timer of 3000 milliseconds is set.     //Results can vary depending on permissions so cmd method of doing this has also been added as backup     boolean reachable = IPAddress.isReachable(1400);      if (reachable){           pingOutput = IPtoPing + " is reachable.\n";     }else{         //runs ping command once on the IP address in CMD         Process ping = Runtime.getRuntime().exec("ping " + IPtoPing + " -n 1 -w 300");         //reads input from command line         BufferedReader in = new BufferedReader(new InputStreamReader(ping.getInputStream()));         String line;         int lineCount = 0;         while ((line = in.readLine()) != null) {             //increase line count to find part of command prompt output that we want             lineCount++;             //when line count is 3 print result             if (lineCount == 3){                 pingOutput = "Ping to " + IPtoPing + ": " + line + "\n";             }         }     }     return pingOutput; } } 

IPtoPing used to be the argument that was taken.

like image 659
DMo Avatar asked Apr 03 '12 12:04

DMo


People also ask

Can we pass parameter in callable?

The first way we can send a parameter to a thread is simply providing it to our Runnable or Callable in their constructor. Note that the reason this works is that we've handed our class its state before launching the thread.

Can callable return a value?

A Callable is similar to Runnable except that it can return a result and throw a checked exception.

Is callable a functional interface?

Interface Callable<V>This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call .

How do you execute a callable in Java?

The Executor Framework gives a submit () method to execute Callable implementations in a pool of threads. In reality, the Java Executor Framework adhers to the WorkerThread patterns. In a thread pool users can initiate threads by using the Executors. newFixedThreadPool(10); method and accordingly submit a task to it.


1 Answers

You can't pass it as the argument to call() because the method signature doesn't allow it.

However, you can pass the necessary information as a constructor argument; e.g.

public class DoPing implements Callable<String>{     private final String ipToPing;      public DoPing(String ipToPing) {         this.ipToPing = ipToPing;     }      public String call() throws SomeException {         InetAddress ipAddress = InetAddress.getByName(ipToPing);         ....     } } 

(I've corrected a couple of egregious code style violations!!)

There are ways to eliminate some of the "boilerplate" coding in the above (see some of the other answers). In this case we are talking about 4 lines of code (in a ~40 line class), so I am not convinced that it is worth the effort. (But hey, it is your code.)

Alternatively, you could:

  • declare DoPing as an inner class (or a lambda) and have it refer to a final ipToPing in the enclosing scope, or

  • add a setIpToPing(String ipToPing) method.

(The last allows a DoPing object to be reused, but the downside is that you will need to synchronize to access it thread-safely.)

like image 126
Stephen C Avatar answered Oct 09 '22 02:10

Stephen C