SimpleDateFormat is not thread-safe: WHY? - Alternatives?
private SimpleDateFormat sdf = null; //NOT thread safe
private DateTimeFormatter formatter = null;//thread safe
private org.apache.commons.lang3.FastDateFormat fdf = null;//thread safe
public void inititialize(String formatStr){
//sdf = new SimpleDateFormat(formatStr);
formatter = DateTimeFormatter.ofPattern(formatStr);
}
public boolean isValidFormat(Object dateStr){sdf.format(dateStr);// not thread safe
formatter.parse(dateStr); //thread safe
}
Java WebApps - UnsatisfiedLinkError - native library
As of Tomcat versions 9.0.13
, 8.5.35
, and 7.0.92
we have added the following options to address this issue BZ-62830:
1) Use the JniLifecycleListener
to load the native library.
e.g. to load the opencv_java343
library, you can use:
<Listener className="org.apache.catalina.core.JniLifecycleListener"
libraryName="opencv_java343" />
2) Use the load()
or loadLibrary()
from org.apache.tomcat.jni.Library
instead of System
.
e.g.
org.apache.tomcat.jni.Library.loadLibrary("opencv_java343");
Using either of those options will use the Common ClassLoader to load the native library, and therefore it will be available to all of the Web Apps.
Java 8 - Streams
Java Process - Fire and Forget
Threads - the old way - t1.start() , t1.join();
/**
* Call 2 expensive methods on separate threads
*
* @throws InterruptedException
*/
public void doMultiThreadedJob() throws InterruptedException {
/* create Runnable using anonymous inner class */
Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("starting expensive task thread t1");
doSomethingExpensive();
System.out.println("finished expensive task thread t1");
}
});
/* start processing on new threads */
t1.start();
/* block current thread until t1 has finished */
t1.join();
}
Executor
allows you to process tasks asynchronously without having to deal with threads directly.Executors
factory class is used to create an instance of an Executor
, either an ExecutorService
or an ScheduledExecutorService
. Some of the most common types of Executor
are described below.Executors.newCachedThreadPool()
— AnExecutorService
with a thread pool that creates new threads as required but reuses previously created threads as they become available.Executors.newFixedThreadPool(int numThreads)
— AnExecutorService
that has a thread pool with a fixed number of threads. ThenumThreads
parameter is the maximum number of threads that can be active in theExecutorService
at any one time. If the number of requests submitted to the pool exceeds the pool size, requests are queued until a thread becomes available.Executors.newScheduledThreadPool(int numThreads)
— AScheduledExecutorService
with a thread pool that is used to run tasks periodically or after a specified delay.Executors.newSingleThreadExecutor()
— AnExecutorService
with a single thread. Tasks submitted will be executed one at a time and in the order submitted.Executors.newSingleThreadScheduledExecutor()
— AnExecutorService
that uses a single thread to execute tasks periodically or after a specified delay.
execute(Runnable)
execute
method takes a Runnable
and is useful when you want to run a task and are not concerned about checking its status or obtaining a result. Think of it as fire and forget asynchronous task.Future<?> submit(Runnable)
execute()
, the submit()
method also takes a Runnable
but differs from execute()
because it returns a Future
. A Future
is an object that represents the pending response from an asynchronous task. Think of it as a handle that can be used to check the status of the task or retrieve its result when the task completes. Futures use generics to allow you to specify the return type of the task. However, given that the Runnablerun()
method has the return type void, the Future
holds the status of the task rather than a pending result. This is represented as Future<?>
in the example below.submit(Runnable)
method is useful when you want to run a task that doesn't return a value but you'd like to check the status of the task after it's been submitted to the ExecutorService
.Checking the Status of a Task
Future
has a few useful methods for checking the status of a task that's been submitted to the ExecutorService
.isCancelled()
checks if the submitted task has already been canceled.isDone()
checks if the submitted task has already completed. When a task has finished,isDone
will return true whether the task completed successfully, unsuccessfully, or was canceled.cancel()
cancels the submitted task. A boolean parameter specifies whether or not the task should be interrupted if it has already started.
submit
method is overloaded to take a Callable
as well as a Runnable
. Like a Runnable
, a Callable
represents a task that is executed on another thread. A Callable
differs from a Runable
because it returns a value and can throw a checked Exception. The Callable
interface has a single abstract method public T call() throws Exception
and like Runable
can be implemented with an anonymous inner class or lambda. The return type of the call()
method is used to type the Future
returned by the ExecutorService
. Two code snippets below show how a Callable
can be created via an anonymous inner class and a lambda expression.Callable
and pass it to the execute
method. The Callable
is executed as soon as a thread is available.Getting a Result from a Future
Callable
is submitted to the ExecutorService
, we receive a Future
with the return type of the call()
method. In the example above, call()
returns a Double
so we get a Future<Double>
. One way of retrieving the result from a Future
is by calling its get()
method. get()
will block indefinitely waiting on the submitted task to complete. If the task doesn't complete or takes a long time to complete, the main application thread will remain blocked.get(long timeout, TimeUnit unit)
method that waits for the specified period of time and if the task hasn't finished (result not available), throws a TimeoutException
.
No comments:
Post a Comment