Note: I'm new to english, so please forgive me for any wrong in it.
I use thread-local for save a resource per-thread; and use it(thread-local) in a some tasks. I run my task by a java executor-service. I would close my resources when a thread going to terminate; then i need run a task in all created threads by executor-service, after me call "executor.shoutdown" method. how i can force executor to run a task per-thread, when it would terminate those?
import java.util.concurrent.*;
public class Main2 {
public static void main(String[] args) {
ExecutorService executor = new ForkJoinPool(3);
SimpleValue val = new SimpleValue();
for(int i=0; i<1000; i++){
executor.execute(new Task(val));
}
executor.shutdown();
while( true ) {
try {
if( executor.awaitTermination(1, TimeUnit.SECONDS) ) System.exit(0);
} catch(InterruptedException intrExc) {
// continue...
}
}
}
protected static interface ResourceProvider<T>
extends AutoCloseable {
public T get();
public ResourceProvider<T> reset() throws Exception;
public ResourceProvider<T> reset(boolean force) throws Exception;
public void close();
}
protected static abstract class ThreadLocalResourceProvider<T>
extends ThreadLocal<T>
implements ResourceProvider<T> {}
protected static class SimpleValue
extends ThreadLocalResourceProvider<String> {
public String initialValue() {
return "Hello " + Thread.currentThread().getName();
}
public SimpleValue reset() throws Exception {
return reset(false);
}
public SimpleValue reset(boolean force) throws Exception{
set(this.initialValue());
return this;
}
public void close() {
remove();
}
}
protected static class Task
implements Runnable {
protected SimpleValue val;
public Task(SimpleValue val) {
this.val = val;
}
#Override
public void run() {
try {
System.out.print(val.reset().get());
} catch( Exception exc ) {
System.out.print( exc.getMessage() );
}
}
}
}
Most executors can be constructed with a ThreadFactory. That's also true for ForkJoinPool. However, for simplification, I use a different ExecutorService.
ExecutorService executor = Executors.newFixedThreadPool(
10, new FinalizerThreadFactory(Executors.defaultThreadFactory()));
The class FinalizerThreadFactory delegates the creation of threads to the passed thread factory. However, it creates threads that will execution some additional code before they exit. That's quite simple:
class FinalizerThreadFactory implements ThreadFactory {
private final ThreadFactory delegate;
public FinalizerThreadFactory(ThreadFactory delegate) {
this.delegate = delegate;
}
public Thread newThread(final Runnable r) {
return delegate.newThread(new Runnable() {
public void run() {
try {
r.run();
} finally {
// finalizer code goes here.
}
}
});
}
}
Related
I have a singleton class and a method with an endless loop. I would like to call that a hundred times with 100 threads inside getInstance. The threads are created, but I only have 60-70 object which are created by the infinite loop.
I'm open to any idea.
I've already tried with newCachedThreadPool and newFixedThreadPool.
public final class MyClass {
private static MyClass instance = null;
public static boolean stop;
private static Map<Integer, CustomBean> pieces = new HashMap<>();
public static MyClass getInstance() {
if (instance == null) {
instance = new MyClass();
for (int i = 0; i < 100; i++) {
Executors.newSingleThreadExecutor().execute(() -> {
try {
endlessMagic();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
return instance;
}
public static void endlessMagic() throws InterruptedException {
while (!stop) {
// where magic happens
pieces.put(something);
Thread.sleep(20);
}
}
}
public class MyClassServletContextListener implements ServletContextListener {
#Override public void contextInitialized(ServletContextEvent servletContextEvent) {
MyClass.getInstance();
}
#Override public void contextDestroyed(ServletContextEvent servletContextEvent) {
MyClass.stop = true;
}
}
I need a correct way how can I implement this using new approach such as ExecutorService. In the Thread we have interrupt(), in the ExecutorService there is shutdown. So, how can I signal all threads to stop? How can I determine that Runnable must stop itself?
public class OldStyle {
public static void main(String[] args) throws InterruptedException {
MyTask task = new MyTask();
task.start();
Thread.sleep(10000);
task.interrupt();
}
static class MyTask extends Thread {
#Override
public void run() {
while (!isInterrupted()) {
// ...do work...
}
}
}
}
I suppose to do something like this, but there is no isInterrupted() :
class ModernWay {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(new MyTask());
executor.shutdown();
executor.awaitTermination(1L, TimeUnit.DAYS);
}
static class MyTask implements Runnable {
#Override
public void run() {
while (!isInterrupted()) {
// ...do work...
}
}
}
}
In class B how can i know jobs of threads are finished? In after properties some worker are running. In class B, I need to know if worker are done?
public class A implements InitializingBean{
public void method1(){
...
}
#Override
public void afterPropertiesSet() throws Exception {
System.out.print("test after properties set");
// send threads to executorService
ExecutorService executorService = Executors
.newFixedThreadPool(4);
for (int i = 0; i < 4; i++) {
Worker worker = new Worker();
executorService.submit(worker);
}
}
}
public class Worker implements Callable<Void>{
#Override
public void call(){
...
}
}
public class B{
public void methodB(){
A a = new A();
a.method1();
///Here How can i know the job of the workers are finished?
}
}
Use a listener/callback pattern to have the thread report completion to a listener. This simple example should show the process:
public interface ThreadCompleteListener {
void workComplete();
}
public class NotifyingThread extends Thread {
private Set<ThreadCompleteListener> listeners;
// setter method(s) for adding/removing listeners to go here
#Override
public void run() {
// do stuff
notifyListeners();
}
private void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.workComplete(); // notify the listening class
}
}
}
in your listening class:
NotifyingThread t = new NotifyingThread();
t.addListener(new ThreadCompleteListener() {
void workComplete() {
// do something
}
});
t.start();
You could use a Future implementation for your thread. It provides a Future#isDone()
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#isDone()
In general, it is usually more useful to be notified via a callback when jobs complete. However, since others have posted answers which follow that model, I'll instead post a solution that simply allows you to poll and ask whether the jobs are finished, in case this is what fits the needs of your application better.
public static interface InitializingBean{
public void afterPropertiesSet() throws Exception;
}
public static class A implements InitializingBean{
private List<Future<Void>> submittedJobs = Collections.synchronizedList(new ArrayList<Future<Void>>());
public void method1(){
//do stuff
}
#Override
public void afterPropertiesSet() throws Exception {
System.out.print("test after properties set");
// send threads to executorService
ExecutorService executorService = Executors
.newFixedThreadPool(4);
synchronized (submittedJobs) {
for (int i = 0; i < 4; i++) {
Worker worker = new Worker();
submittedJobs.add(executorService.submit(worker));
}
}
}
/**
* Allows you to poll whether all jobs are finished or not.
* #return
*/
public boolean areAllJobsFinished(){
synchronized (submittedJobs) {
for(Future<Void> task : submittedJobs){
if(!task.isDone()){
return false;
}
}
return true;
}
}
}
public static class Worker implements Callable<Void>{
#Override
public Void call(){
//do worker job
return null; //to satisfy compiler that we're returning something.
}
}
public static class B{
public void methodB(){
A a = new A();
a.method1();
if(a.areAllJobsFinished()){
System.out.println("Congrats, everything is done!");
} else {
System.out.println("There's still some work being done :-(");
}
}
}
If you'd like to wait in that thread that starts the ExecutorService, you can actually use the awaitTermination method.
At the end of you afterPropertiesSet method, you should add:
executorService.shutdown();
After this you then add:
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)
This causes the thread to wait for all the executorService's tasks to be done and then continues. So place any code you want to execute after the call to awaitTermination.
I currently have several runnable classes, each printing a string upon completion using System.out.println().
In the main() I execute them using a ExecutorService ,executor.execute() for each of them.
I am wondering after executing those threads, how to get the output stream from them for future use ?
Pretty much like using .getInputStream for processes but there's no such method in the Thread class. Thanks!
There's a class which implements runnable interface like this:
public class A implements Runnable {
public void run() {
System.out.println(5); //this thread always print out number 5
}
}
and in the main function I need to get the printed number and store it
public static void main(String[] args) {
ExecutorService ThreadPool = Executors.newFixedThreadPool(1);
ThreadPool.execute(new A()); //This statement will cause the thread object A
//to print out number 5 on the screen
ThreadPool.shutdown();
......
}
Now I need to get the printed number 5 and store it into, say an integer variable.
I think below code will satisfy your requirement.
class MyCallable implements Callable<InputStream>
{
#Override
public InputStream call() throws Exception {
//InputStream inputStreamObject = create object for InputStream
return inputStreamObject;
}
}
class Main
{
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Future<InputStream>> list = new ArrayList<Future<InputStream>>();
for (int i = 0; i < 25; i++) {
Callable<InputStream> worker = new MyCallable();
Future<InputStream> submit = executor.submit(worker);
list.add(submit);
}
InputStream inputStreamObject = null;
for (Future<InputStream> future : list) {
try {
inputStreamObject = future.get();
//use inputStreamObject as your needs
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
Runnable and Callable in thread:
runnable interface has a method public abstract void run(); void - which means after completing run method, it will not return anything. Callable<V> interface has a method V call() throws Exception; which means after completing call method, it will return Object V that is parametrized as
public class Run_Vs_Call {
public static void main(String...args){
CallableTask call = new CallableTask();
RunnableTask run = new RunnableTask();
try{
FutureTask<String> callTask = new FutureTask<String>(call);
Thread runTask = new Thread(run);
callTask.run();
runTask.start();
System.out.println(callTask.get());
}catch(Exception e){
e.printStackTrace();
}
}
public static class CallableTask implements Callable<String>{
public String call( ){
String stringObject = "Inside call method..!! I am returning this string";
System.out.println(stringObject);
return stringObject;
}
}
public static class RunnableTask implements Runnable{
public void run(){
String stringObject = "Inside Run Method, I can not return any thing";
System.out.println(stringObject);
}
}
}
you can use new static class:
public class Global{
//example
public static ..
public static ..
}
I just noticed the following phenomena when cancelling a Future returned by ForkJoinPool. Given the following example code:
ForkJoinPool pool = new ForkJoinPool();
Future<?> fut = pool.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
while (true) {
if (Thread.currentThread().isInterrupted()) { // <-- never true
System.out.println("interrupted");
throw new InterruptedException();
}
}
}
});
Thread.sleep(1000);
System.out.println("cancel");
fut.cancel(true);
The program never prints interrupted. The docs of ForkJoinTask#cancel(boolean) say:
mayInterruptIfRunning - this value has no effect in the default implementation because interrupts are not used to control cancellation.
If ForkJoinTasks ignore interrupts, how else are you supposed to check for cancellation inside Callables submitted to a ForkJoinPool?
This happens because Future<?> is a ForkJoinTask.AdaptedCallable which extends ForkJoinTask, whose cancel method is:
public boolean cancel(boolean mayInterruptIfRunning) {
return setCompletion(CANCELLED) == CANCELLED;
}
private int setCompletion(int completion) {
for (int s;;) {
if ((s = status) < 0)
return s;
if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) {
if (s != 0)
synchronized (this) { notifyAll(); }
return completion;
}
}
}
It does not do any interruptions, it just sets status. I suppose this happens becouse ForkJoinPools's Futures might have a very complicated tree structure, and it is unclear in which order to cancel them.
Sharing some more light on top of #Mkhail answer:
Using ForkJoinPool execute() instead of submit() will force a failed Runnable to throw a worker exception, and this exception will be caught by the Thread UncaughtExceptionHandler.
Taking from Java 8 code:
submit is using AdaptedRunnableAction().
execute is using RunnableExecuteAction() (see the rethrow(ex)).
/**
* Adaptor for Runnables without results
*/
static final class AdaptedRunnableAction extends ForkJoinTask<Void>
implements RunnableFuture<Void> {
final Runnable runnable;
AdaptedRunnableAction(Runnable runnable) {
if (runnable == null) throw new NullPointerException();
this.runnable = runnable;
}
public final Void getRawResult() { return null; }
public final void setRawResult(Void v) { }
public final boolean exec() { runnable.run(); return true; }
public final void run() { invoke(); }
private static final long serialVersionUID = 5232453952276885070L;
}
/**
* Adaptor for Runnables in which failure forces worker exception
*/
static final class RunnableExecuteAction extends ForkJoinTask<Void> {
final Runnable runnable;
RunnableExecuteAction(Runnable runnable) {
if (runnable == null) throw new NullPointerException();
this.runnable = runnable;
}
public final Void getRawResult() { return null; }
public final void setRawResult(Void v) { }
public final boolean exec() { runnable.run(); return true; }
void internalPropagateException(Throwable ex) {
rethrow(ex); // rethrow outside exec() catches.
}
private static final long serialVersionUID = 5232453952276885070L;
}