I want to know about what is the best way to develop a thread pool in java to
do multitask and ,how to stack memory keep it when this sample program executing .
please explain me about what is the best way to implement thread pool?
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;
class A implements Runnable {
#Override
public void run() {
System.out.println("A "+Thread.currentThread().getName());
}
}
class B implements Runnable {
#Override
public void run() {
System.out.println("B "+Thread.currentThread().getName());
}
}
class C implements Runnable {
#Override
public void run() {
System.out.println("C "+Thread.currentThread().getName());
}
}
public class threadrunner {
public static void main(String[] args) {
ExecutorService bn = Executors.newFixedThreadPool(2);
Runnable t1 = new A();
Runnable t2 = new B();
Runnable t3 = new C();
bn.execute(t1);
bn.execute(t2);
bn.execute(t3);
bn.shutdwon();
}
}
Related
I am trying to run an Infinite loop in my JavaFX app.
An infinite while loop is present in my code in the Kulta.java file.
This loop actually freezes my app.
While the same thing works when I port the app to normal javax.swing.
Now since java.lang.Thread doesn't work for javafx, I came accross javafx.concurrent.Task,
which is not working as intended. As one of the main features of multithreading, i.e. running an infinite loop in a GUI app, is not served properly, please help me with the solution.
This is my code:
Urania.java
import java.awt.Toolkit;
import java.awt.Dimension;
import javax.swing.SwingUtilities;
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
public class Urania {
public static final Dimension DIMENSION = Toolkit.getDefaultToolkit().getScreenSize();
public static void main(String[] args) {
SwingUtilities.invokeLater(
new Runnable() {
#Override
public void run() {
Kulta kulta = new Kulta();
kulta.setTitle("Abha K Pauri");
kulta.setSize(DIMENSION.width/2, DIMENSION.height/2);
kulta.setLocationRelativeTo(null);
kulta.setDefaultCloseOperation(EXIT_ON_CLOSE);
kulta.setVisible(true);
}
}
);
}
}
And here is my JFrame in which I have embedded my JavaFX app.
Kulta.java
import javax.swing.JFrame
import javafx.embed.swing.JFXPanel;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.control.Button;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.concurrent.Task;
public class Kulta extends JFrame {
private JFXPanel fxpanel;
private Scene scene;
private BorderPane borderpane;
private Button button;
public static final String INVOKE = "INVOKE";
public static final String INTERRUPT = "INTERRUPT";
public static final String[] COLORS = new String[]{"yellow", "pink", "green", "blue", "orange"};
public Kulta() {
fxpanel = new JFXPanel();
add(fxpanel);
Platform.runLater(
new Runnable() {
#Override
public void run() {
Kulta.this.setScene();
Kulta.this.setButton();
Kulta.this.setListener();
}
}
);
}
private void setScene() {
borderpane = new BorderPane();
scene = new Scene(borderpane);
fxpanel.setScene(scene);
}
private void setButton() {
button = new Button(INVOKE);
borderpane.setTop(button);
}
private void setListener() {
Event event = new Event();
button.setOnAction(event);
}
private class Event implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent event) {
boolean flag = true;
Task<Void> onInvoke = new Task<Void>() {
#Override
public Void call() {
int count = 0;
flag = true;
button.setText(INTERRUPT);
/* This loop freezes the app. */
while(flag) {
borderpane.setStyle("-fx-color: "+COLORS[count]+";");
count++;
if(count == COLORS.length)
count = 0;
}
return null;
}
};
Task<Void> onInterrupt = new Task<Void>() {
#Override
public Void call() {
button.setText(INVOKE);
if(flag)
flag = false; // This will stop the onInvoke thread
return null;
}
};
Task<Void> change = new Task<Void>() {
#Override
public Void call() {
if(button.getText().equals(INVOKE))
onInvoke().run();
else if(button.getText().equals(INTERRUPT))
onInterrupt().run();
}
};
change.run();
}
}
}
How should I write the loop in order to not let the app freeze.
Any code, solution, link or any help in any form will help a lot.
Thanks in advance.
What is the correct way to manipulate an Observable collection in a thread, where the collection is already bound to a JavaFX UI-node?
In my sample application, the connection between the collection and the nodes are broken before the thread can do any manipulation; and then they are re-connected after the thread is done. The methods are disconnectObservable() and connectObservable() respectively. Without these two methods, java.lang.IllegalStateException: Not on FX application thread is reported.
Ideally I would like ChangeObservableTask to make its changes to mWords, and then I would call some method to tell mObservable to refresh itself and notify its listeners. Is there such a thing?
Thanks.
package theapp;
import java.util.LinkedList;
import java.util.List;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ThreadObList extends Application {
private final List<String> mWords;
private final ObservableList<String> mObservable;
private ListView mListView;
private Label mCount;
public ThreadObList() {
mWords = new LinkedList<>();
mObservable = FXCollections.observableList(mWords);
mWords.add("park");
}
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Start thread");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
ChangeObservableTask task = new ChangeObservableTask();
Thread thd = new Thread(task);
disconnectObservable();
thd.start();
try {
task.get();
System.out.println("ChangeObservableTask exited normally.");
}
catch(Exception ex) {
System.out.println(ex.getMessage());
}
connectObservable();
}
});
mCount = new Label();
mListView = new ListView();
VBox root = new VBox(5, btn, mCount, mListView);
VBox.setVgrow(mListView, Priority.ALWAYS);
connectObservable();
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private void connectObservable() {
mListView.setItems(mObservable);
mCount.textProperty().bind(Bindings.size(mObservable).asString());
}
private void disconnectObservable() {
mListView.setItems(null);
mCount.textProperty().unbind();
}
private class ChangeObservableTask extends Task<Void> {
#Override
protected Void call() throws Exception {
mObservable.add("dart");
mObservable.add("truck");
mObservable.add("ocean");
return null;
}
}
}
Once the list is used as the contents of the ListView, you can only manipulate it from the FX Application Thread. See the Task javadocs for a bunch of usage examples.
You can create a copy of your ObservableList and pass it to your task, manipulate the copy and return the results. Then update the ObservableList with the results in the onSucceeded handler.
Also note that you shouldn't make any blocking calls, such as task.get() on the FX Application Thread, as you can make the UI unresponsive by doing so.
So you should do something along the lines of:
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
ChangeObservableTask task = new ChangeObservableTask(new ArrayList<>(mObservable));
Thread thd = new Thread(task);
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
mObservable.setAll(task.getValue());
}
});
thd.start();
}
});
and
private class ChangeObservableTask extends Task<List<String>> {
private final List<String> data ;
ChangeObservableTask(List<String> data) {
this.data = data ;
}
#Override
protected List<String> call() throws Exception {
data.add("dart");
data.add("truck");
data.add("ocean");
return data;
}
}
Is it possible to fire an event in a NamedBean asynchronously and to wait till all Consumers (Observers) are finished? The Consumer (Observers) should run asynchronously, but the event should be finished if all of them are finished.
e.g. I have 3 Beans (1 Bean which fires the event and 2 which observes the event).
Bean which fires the event:
#Named
#Stateless
public class TestExecuter implements Serializable {
#Inject
#MyEvent
private Event<QueryTO> myEvent;
public void run() {
QueryTO queryTO = new QueryTO(null, null);
FilterQualifier[] qualifiers = new FilterQualifier[3];
qualifiers[0] = new FilterQualifier(TestA.FILTER_ID);
qualifiers[1] = new FilterQualifier(TestB.FILTER_ID);
System.out.println("Fire event");
myEvent.select(qualifiers).fire(queryTO);
//wait till observers are finished
System.out.println("Event finished");
}
}
Bean 1 which observes
#Named
#Stateless
public class TestA implements Serializable {
public static final String FILTER_ID = "TestA";
public void generateFilterQueryEvent(
#Observes #Filter(FILTER_ID) #MyEvent QueryTO queryTo) {
System.out.println("TestA called");
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
System.out.println("TestA finished");
}
}
Bean 2 which observes
#Named
#Stateless
public class TestB implements Serializable {
public static final String FILTER_ID = "TestB";
public void generateFilterQueryEvent(
#Observes #Filter(FILTER_ID) #MyEvent QueryTO queryTo) {
System.out.println("TestB called");
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
System.out.println("TestB finished");
}
}
Expected result: Both beans execute the code at the same time and after 3 seconds the event is finished and the event is finished. Currently it executes TestA and after that TestB, so I have to wait 5 seconds.
AFAIK it's not supported by CDI although you can workaround it with an custom AsyncEvent class which gets the observers and calls them in separate threads. Here is a proof of concept example:
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.ObserverMethod;
import javax.enterprise.util.AnnotationLiteral;
import javax.inject.Inject;
public class AsyncEvent<T> {
private static final AnnotationLiteral<Any> ANY =
new AnnotationLiteral<Any>() {
};
#Inject
private BeanManager beanManager;
private ExecutorService executorService;
public AsyncEvent() {
}
#PostConstruct
public void init() {
executorService = Executors.newFixedThreadPool(5);
}
#PreDestroy
public void shutdown() {
try {
executorService.shutdown();
final boolean terminated = executorService.awaitTermination(10, TimeUnit.SECONDS);
if (!terminated) {
throw new RuntimeException("awaitTermination timeout");
}
} catch (final InterruptedException ie) {
throw new RuntimeException(ie);
}
}
public void fire(final T event) {
fire(event, ANY);
}
public void fire(final T event, final Annotation... qualifiers) {
final Set<ObserverMethod<? super T>> observers = beanManager.resolveObserverMethods(event, qualifiers);
final Set<Callable<Void>> tasks = createCallablesForObservers(event, observers);
invokeAll(tasks);
}
private Set<Callable<Void>> createCallablesForObservers(final T event,
final Set<ObserverMethod<? super T>> observers) {
final Set<Callable<Void>> tasks = new HashSet<Callable<Void>>();
for (final ObserverMethod<? super T> observer: observers) {
final Callable<Void> callable = createCallable(event, observer);
tasks.add(callable);
}
return tasks;
}
private Callable<Void> createCallable(final T event,
final ObserverMethod<? super T> observer) {
final Callable<Void> callable = new Callable<Void>() {
#Override
public Void call() {
observer.notify(event);
return null;
}
};
return callable;
}
private void invokeAll(final Set<Callable<Void>> tasks) {
try {
executorService.invokeAll(tasks);
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Usage:
private static final AnnotationLiteral<Updated> UPDATED = new AnnotationLiteral<Updated>() {
};
#Inject
private AsyncEvent<Document> event;
public void run() {
System.out.println("Fire event");
final Document document = new Document("test event");
event.fire(document);
event.fire(document, UPDATED);
...
}
I am testing an application.
My test is complex, and I spawn 2 thread that start 2 process builders which spawn 2 java processes.
Is it possible to write a custom redirect that will be similar to inherit but prepend something to every out and err message, so that I would know its origin.
Example code below:
public class test {
public static void main(String... args){
Thread t = new Thread(new testHelper());
t.start();
t = new Thread(new testHelper());
t.start();
}
}
import java.io.IOException;
public class testHelper implements Runnable {
#Override
public void run() {
Class klass = testWorker.class;
System.out.println(klass.getCanonicalName());
String separator = System.getProperty("file.separator");
String classpath = System.getProperty("java.class.path");
String path = System.getProperty("java.home")
+ separator + "bin" + separator + "java";
ProcessBuilder processBuilder =
new ProcessBuilder(path, "-cp",
classpath,
klass.getCanonicalName());
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
processBuilder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
Process process = null;
try {
process = processBuilder.start();
} catch (IOException e) {
e.printStackTrace();
}
try {
process.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Child Process is done");
}
}
public class testWorker {
public static void main(String ... args) throws InterruptedException {
System.out.println("Doing some stuff");
Thread.sleep(10000);
System.out.println("Finished doing some stuff");
}
}
No, its not possible. In the source code for java.lang.ProcessBuilder.Redirect the constructor is private and has this to say
/**
* No public constructors. Clients must use predefined
* static {#code Redirect} instances or factory methods.
*/
private Redirect() {}
i have a JSF web application deployed under glassfish in which i have two buttons.The first start a infinite thread and the second stop it.My problem is that i can not stop a running thread.I have searched for a solution on the net but in vain.it works in case i have a J2SE application but not with a J2EE application here is my code
package com.example.beans;
import org.apache.commons.lang.RandomStringUtils;
public class MyBusinessClass {
public static void myBusinessMethod() {
/* this method takes a lot of time */
int i = 1;
while (i == 1) {
String random = RandomStringUtils.random(3);
System.out.println(random);
}
}
}
package com.example.beans;
import java.util.Random;
import java.util.TimerTask;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.log4j.Logger;
import com.example.core.RandomUtils;
public class MySimpleRunnableTask implements Runnable {
private Logger logger = Logger.getLogger(MySimpleRunnableTask.class);
#Override
public void run() {
MyBusinessClass.myBusinessMethod();
}
}
#ManagedBean(name = "MainView")
#SessionScoped
public class MainView {
private static Thread myThread;
#SuppressWarnings({ "unchecked", "rawtypes", "deprecation" })
public String startSimpleThread() throws SecurityException,
NoSuchMethodException,
InterruptedException {
MySimpleRunnableTask mySimpleRunnableTask = new MySimpleRunnableTask();
myThread = new Thread(mySimpleRunnableTask);
myThread.start();
return null;
}
#SuppressWarnings({ "unchecked", "rawtypes", "deprecation" })
public String stopSimpleThread() throws SecurityException,
NoSuchMethodException,
InterruptedException {
myThread.interrupt();
return null;
}
}
I have changed my code so you can understand really what's my problem
interrupt only sets the interrupt status in the thread to true. The thread needs to regularly pool the interrupt status flag to stop running:
public void run() {
/* you will have to touch the code here */
int i = 1;
while (i == 1) {
String random = RandomStringUtils.random(3);
logger.info(random);
if (Thread.currentThread().isInterrupted()) {
// the thread has been interrupted. Stop running.
return;
}
}
}
This is the only way to properly stop a thread : ask him to stop. Without cooperation from the running thread, there is no clean way.