In JavaScript, it is possible to write a self-executing function like this:
(function foo() {
console.log("bar");
}());
I'm looking to do this in Java. So for example:
// This code does not work obviously
public static void main(String[] args) {
(foo() {
System.out.println("bar");
}());
}
Is there such a thing?
As others have said, there's not much reason to do this in Java, since the reasons for doing it in JavaScript aren't problems in Java. But you could do this in Java 8:
((Runnable)(() -> System.out.println("Hello, world"))).run();
which in essence is the same thing #yshavit's answer did in Java 7.
That javascript isn't really creating a "self-executing" function. It's defining a function, and then immediately executing it.
Java doesn't let you define standalone functions, so you can't do this in Java. You can however declare an anonymous class and immediately execute one of its methods:
new Runnable() {
#Override
public void run() {
System.out.println("hello");
}
}.run();
This is sometimes done with new threads. Something like:
new Thread(new Runnable() {
// override Runnable.run
}).start();
(Though in a lot of cases, you'll want to do better thread management -- submit the runnable to an executor service, for instance.)
You can create helper methods (for e.g. run and get) that will execute your custom function.
use run if function doesn't return anything (side effects) and get otherwise
import java.util.function.Supplier;
public interface MyApp {
static void run(Runnable supp) {
supp.run();
}
static <R> R get(Supplier<R> supp) {
return supp.get();
}
static void test() {
run(() -> System.out.println("bar"));
var v = get(() -> "Hello");
}
}
Related
I have an application with a couple runAsync(). These runAsync() call a variety of other methods, and I'd like to run some code before each of them but within the same thread.
So for example I have main thread, then I call runAsync(MyClass::myMethod), Thread1 is created and before myMethod() gets called, within the same thread (Thread1), another method is called.
I assume this would involve some kind of wrapper of some sorts but since this uses lambda expressions and async threads I'm a bit lost on how that'd be done.
Thanks in advance
Edit: I'd like to clarify that methodToRunBeforeAsync() should be hidden from other devs. Something like using a wrapper so you don't have to worry to make the calls to methodToRunBeforeAsync()
In order to run code around those lambdas there are a couple of options. One would be AOP but that can be complex to set up so if you're able to change the calls, you could do the following:
Option 1: Create a WrapperRunnable
Just create a wrapper/decorator that executes whatever additional code you need. You can use that approach wherever a Runnable is required.
class WrapperRunnable implements Runnable {
Runnable delegate;
WrapperRunnable(Runnable r) {
delegate= r;
}
public void run() {
//any code before
delegate.run();
//any code after
}
}
Usage: CompletableFuture.runAsync(new WrapperRunnable(MyClass::myMethod))
Option 2: wrap runAsync()
Provide your own runAsync(Runnable) method that internally creates a decorator lambda or uses the decorator defined in option 1. That calls CompletableFuture.runAsync() internally and can only be used as a replacement for this method.
class MyCompletables {
public static CompletableFuture<Void> runAsync(Runnable runnable) {
return CompletableFuture.runAsync(() -> {
//any code before
runnable.run();
//any code after
});
}
}
Using the decorator of option 1:
class MyCompletables {
public static CompletableFuture<Void> runAsync(Runnable runnable) {
return CompletableFuture.runAsync(new WrapperRunnable(runnable));
}
}
Usage: MyCompletables.runAsync(MyClass::myMethod)
Note that there are other options as well, some being more flexible, some more elegant, but this should get you started while still being easy to understand.
Something like this? Just wrap the task and make sure people use myRunAsync instead of the standard one. Give it a better name, obviously.
public static void main(String[] args) {
myRunAsync(() -> System.out.println("Task")).join();
}
private static CompletableFuture<Void> myRunAsync(Runnable runnable) {
return CompletableFuture.runAsync(() -> {
preTask();
runnable.run();
});
}
private static void preTask() {
System.out.println("Pre");
}
One simple example would be:
runAsync(() -> {
myOtherObject.myMethodToRunBefore();
myObject.myMethod();
}
)
You can either add the call to myMethodToRunBefore() in the first line of the body myMethod() or create wrapper object.The choice depends if the myMethod should be separated from the call to myMethodToRunBefore (then use wrapper) or they always need to be called together in same order (then add the call to the beforeMethod in the first line of myMethod).
Sorry if this was asked, but I keep wondering and weren't able to google up solution and not for luck of trying.
When implementing Command pattern inside one class, this one-method interface keeps popping up in all places.
public interface Command {
void execute();
}
Then it gets reused plenty of times like this:
public void doAction1()
{
perform(new Command () {
#Override
public void execute()
{
//do some crazy stuff
}
});
}
public void doAction2()
{
perform(new Command () {
#Override
public void execute()
{
//do some event crazier stuff
}
});
}
public void doAction3()
{
perform(new Command () {
#Override
public void execute()
{
//do a barrel roll
}
});
}
private void perform(Command command)
{
command.execute();
}
Different namings, different modules, different software even --- but this one gets reimplemented over and over, cluttering source and doing essentially nothing new.
Is there any generic, OOB one-method interface that's OK to use instead of creating my own every time I need lambda-like sentence? Is it OK to use Runnable in this way? Wouldn't it create confusion in the mind of some future source code-reader?
PS: Now, I know, that there's java 1.8 with lambdas and all, but at my work we're stuck with 1.6 for the moment (enterprise customers are so enterprise), so I'd appreciate some archeological help here.
Yes, Runnable or Callable (if you need to return a result) are perfectly fine to use.
I am beginner in java. I have been studying multithreading. I want to create two threads and these two threads must run separate methods concurrently. Here these threads should call sum and diff method and run simultaneously. But I am getting an error, that method should be of thread type. How to achieve it.
class Demo implements Runnable
{
void sum()
{
//Some lines of code
}
void diff()
{
//Some lines of code
}
public void run ()
{
System.out.println("Inside run");
}
}
class Test
{
public static void main (String []args){
Demo o = new Demo ();
Demo o1 = new Demo ();
Thread th = new Thread (o);
Thread th1= new Thread(o1);
th.start();
th1.start();
o.th.sum(); // getting error here
o1.th1.diff(); // getting error here
}
}
First of all you have a compilation error because you're trying to reference the variable th as a field on an object of type Demo. th is not a field, but rather a local variable and can be referenced directly (i.e. without the o. prefix). Second, sum() and diff() cannot be called against an instance of Thread as those methods are not defined by thread, but rather by your own Demo class.
All that being said, these compilation problems aren't even the root issue for this code. Based on your code it seems you have some fundamental misunderstandings about the syntax and structure of Java programs so it might benefit you to go through some entry-level tutorials before trying to tackle concurrent programming. But, for the sake of completeness here is a brief explanation of what you need to do in order to make your program work.
When you call Thread.start() it's going to fork a thread and call the run() method of the Runnable you passed into that thread object's constructor.
In order to call the two different methods you need to create two different classes that implement runnable and put the two method implementations in each of their run methods.
Example:
public class Sum implements Runnable {
public void run() {
//Add up your numbers
}
}
public class Diff implements Runnable {
public void run() {
//Subtract numbers
}
}
public class Test {
public static void main(String[] args) {
Thread sumThread = new Thread(new Sum());
Thread diffThread = new Thread(new Diff());
sumThread.start();
diffThread.start();
}
}
Assuming that you are getting a compilation error, the statement o.th.sum() is incorrect.
The statement o.th will cause the compiler to look for a public static class level field in the Demo class with the name th. Since there is no such field in Demo class, you get an error.
You are getting this error because you are trying to access the Thread's local variable using the object of the Demo class and you can't call the method directly if you want's it to run it in a separate thread. A new thread will spawn only when you call start() method on thread class and then it will execute the code in run() method.
As per your requirement to create two threads and these two threads must run separate methods concurrently, following code should work.
class Demo implements Runnable
{
public void run ()
{
//sum() method code
}
}
class Demo1 implements Runnable
{
public void run ()
{
//diff() method code
}
}
class Test
{
public static void main (String []args){
Demo o = new Demo ();
Demo1 o1 = new Demo1 ();
Thread th = new Thread (o);
Thread th1= new Thread(o1);
th.start();
th1.start();
}
}
I'm writing small app and now I discovered a problem.
I need to call one(later maybe two) method (this method loads something and returns the result) without lagging in window of app.
I found classes like Executor or Callable, but I don't understand how to work with those ones.
Can you please post any solution, which helps me?
Thanks for all advices.
Edit: The method MUST return the result. This result depends on parametrs.
Something like this:
public static HtmlPage getPage(String page) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
return webClient.getPage(page);
}
This method works about 8-10 seconds. After execute this method, thread can be stopped. But I need to call the methods every 2 minutes.
Edit: I edited code with this:
public static HtmlPage getPage(final String page) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
Thread thread = new Thread() {
public void run() {
try {
loadedPage = webClient.getPage(page);
} catch (FailingHttpStatusCodeException | IOException e) {
e.printStackTrace();
}
}
};
thread.start();
try {
return loadedPage;
} catch (Exception e) {
return null;
}
}
With this code I get error again (even if I put return null out of catch block).
Since Java 8 you can use shorter form:
new Thread(() -> {
// Insert some method call here.
}).start();
Update:
Also, you could use method reference:
class Example {
public static void main(String[] args){
new Thread(Example::someMethod).start();
}
public static void someMethod(){
// Insert some code here
}
}
You are able to use it when your argument list is the same as in required #FunctionalInterface, e.g. Runnable or Callable.
Update 2:
I strongly recommend utilizing java.util.concurrent.Executors#newSingleThreadExecutor() for executing fire-and-forget tasks.
Example:
Executors
.newSingleThreadExecutor()
.submit(Example::someMethod);
See more: Platform.runLater and Task in JavaFX, Method References.
Firstly, I would recommend looking at the Java Thread Documentation.
With a Thread, you can pass in an interface type called a Runnable. The documentation can be found here. A runnable is an object that has a run method. When you start a thread, it will call whatever code is in the run method of this runnable object. For example:
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// Insert some method call here.
}
});
Now, what this means is when you call t.start(), it will run whatever code you need it to without lagging the main thread. This is called an Asynchronous method call, which means that it runs in parallel to any other thread you have open, like your main thread. :)
In Java 8 if there is no parameters required you can use:
new Thread(MyClass::doWork).start();
Or in case of parameters:
new Thread(() -> doWork(someParam))
I have a lot of methods for logging, like logSomeAction, logAnotherAction etc.
Now I want all these methods make a small pause after printing messages (Thread.sleep).
If I do it manually, I would do something like this:
//before:
public static void logSomeAction () {
System.out.println (msg(SOME_ACTION));
}
//after:
public static void logSomeAction () {
System.out.println (msg(SOME_ACTION));
try {
Thread.sleep (2000);
} catch (InterruptedException ignored) { }
}
I remember that Java has proxy classes and some other magic-making tools. Is there any way avoid copy-n-pasting N sleep-blocks to N logging methods?
You could use Aspects to add extra "orthogonal" functionality to your methods.
If that sounds too esoteric, a simpler, down-to-earth solution would be to add the sleep in a separate method, then call that method in each of your logging methods. The first time you do this, you need to touch each method, but the next time if you want to modify the extra behaviour or add something else, you can do it in one single place.
It looks like you want to use Aspect Oriented Programming. You could use Spring for AOP, or AspectJ.
The OP mentions in a comment that the preferred solution is to use plain java proxies. The current code is implemented as static methods - for java proxies to be of any use, the logger class will need to be reworked as an interface. Something like this:
public interface SomeActionLogger
{
void logSomeAction();
void logSomeOtherAction();
// etc..
}
You then create your concrete implementation
public class SystemOutActionLogger implements SomeActionLogger
{
public void logSomeAction () {
System.out.println (msg(SOME_ACTION));
}
}
You can then have Java proxies wrap the SomeActionLogger interface
class DelayAfterInvocationHandler implements InvocationHandler
{
private Object delegate;
private int duration;
DelayAfterInvocationHandler(Object delegate, int duration)
{
this.delegate = delegate;
this.duration = duration;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
Object returnValue = method.invoke(delegate, args);
Thread.sleep(duration);
// you may want to catch InterruptedEception
return returnValue;
}
}
To hide some of the not-so-pretty proxy code, you can then have a method that wraps your logger to create the delay, e.g.
public ActionLogger addDelay(SomeActionLogger logger, int delay)
{
return (ActionLogger)Proxy.newProxyInstance(
impl.getClass().getClassLoader(),
new Class[] { SomeActionLogger.class },
new DelayAfterInvocationHandler(logger, delay));
}
So you then write
SomeActionLogger log = addDelay(new SystemOutActionLogger(), 2000);
Note that the DelayInvocationHandler is orthogonal to the logging interface - it can be used to add delay to any interface. You might then create a generic wrapping method like this:
public <T> T addDelay(T delegate, int delay, Class<T> interfaceType)
{
return (T)Proxy.newProxyInstance(
delegate.getClass().getClassLoader(),
new Class[] { type },
new DelayAfterInvocationHandler(delegate, delay));
}
Make a utility class that has a static SleepFor method which includes your try ... catch block and call that from every method you want a sleep in?
Replace all the System.out.println(msg(SOME_ACTION)); with printAndWait(SOME_ACTION);
You should be able to do that with find and replace.
Then create a method
public static void printAndWait(Object someAction) {
System.out.println (msg(someAction));
try {
Thread.sleep (2000);
} catch (InterruptedException ignored) {
Thread.currentThread.interrupt();
}
}
That way the code appears once and you can change it easily in one place.
Replace all of your logSomeAction() methods with a single logAction(Action a) method. This way, when you add more actions in the future, you will not be repeating your code for handling the action log and the thread sleep.