Can someone advise how to create new threads in a loop. Data are retrieved from the database and I want to make each row was processed in a new thread. Everything happens in the controller JavaFX. You probably need to use the service but I can not find an example of this approach. Thanks in advance
Are you sure you want to create a new thread for every row? If you have a million rows, you will have a million threads.
If so, it should be as simple as this:
ResultSet rs = ...;
while (rs.next()) {
new Thread(() -> {
doSomething();
Platform.runLater(() -> doSomethingThatUpdatesUI());
}).start();
}
Update
An example using javafx.concurrent.Task (only one thread created):
Task task = new Task<Void>() {
#Override
public Void call() {
ResultSet rs = ...;
int max = getSizeOfResultSet(rs);
int count = 0;
while (rs.next()) {
if (isCancelled()) {
break;
}
updateProgress(count++, max);
}
return null;
}
};
yourProgressBarIfYouHaveOne.progressProperty().bind(task.progressProperty());
new Thread(task).start();
task.setOnSucceeded(event -> {
System.out.println("OK, all done!");
releaseUserInterface();
});
Related
I want to back up rocksdb while not blocking my writing calls, the status I expected is rocksdb should back up the data at that moment and ignoring the writing calls while backing up, is there a proper way to accomplish this?
I tested this in java using rocksdb-jni:
RocksDB.loadLibrary();
RocksDB rocksDb = RocksDB.open("C:/rocksdb/data");
BackupEngine engine = BackupEngine.open(rocksDb.getEnv(), new BackupEngineOptions("C:/rocksdb/backup"));
for(int i = 0;i < 100000;i++){
byte[] k = ByteBuffer.allocate(4).putInt(0, i).array();
rocksDb.put(k,k);
}
ExecutorService executorService = Executors.newFixedThreadPool(2);
CountDownLatch countDownLatch = new CountDownLatch(1);
executorService.execute(() -> {
try {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
countDownLatch.await();
engine.createNewBackup(rocksDb, false);
} catch (RocksDBException | InterruptedException e) {
throw new RuntimeException(e);
}
});
executorService.execute(() -> {
try {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
countDownLatch.await();
//Thread.sleep(1);
for(int i = 100000;i < 200000;i++){
byte[] k = ByteBuffer.allocate(4).putInt(0, i).array();
rocksDb.put(k,k);
}
} catch (InterruptedException | RocksDBException e) {
throw new RuntimeException(e);
}
});
countDownLatch.countDown();
the result I expected from restoring is exactly 100000 records, but I always got more records
Yes - both backup and checkpoint engines can achieve this i.e. take a live backup while not blocking writes
https://github.com/facebook/rocksdb/wiki/How-to-backup-RocksDB
Im facing a potential chase error. Im using javafx TableView to display my data, and I'm periodically receiving an update request externally which calls my update function. I also have some listeners which does stuff such as handle mousedrag events etc. What i want to do is to do something like this:
private void handleEvent(){
TableView.setRowFactory(new Callback<TableView<MyModel>, TableRow<MyModel>>(){
public TableRow<MyModel> call(TableView<MyModel> p) {
final TableRow row = new TableRow();
row.setOnDragDetected(new EventHandler<MouseEvent>(){
public void handle(){
//implement some kind of lock to prevent receiving data update
}
}
row.setOnMouseDragExited(new EventHandler<MouseDragEvent>(){
//release lock to accept update
}
}
}
//this method is being called externally periodically
public void updateModel(MyModel model){
//this won't work because it will skip entirely if it's locked,
//I want it to instead run later when lock is released
if (!locked){
this.model = model;
}
}
I did a quick workaround by using a Boolean to lock and unlock as shown in updateModel Method, problem with that is it will lose some updated data because it's skipped entirely.. instead, I want it to run later when lock is released.. how can I implement this kind of lock mechanism and run later feature?
Edit: why I suspect this is because my listeners are manipulating and getting table data.. while the data is constantly updated, I'm not sure if this is causing my table to break.
Just write some logic that collects everything you tried to do in a locked state and executes it on unlocking.
The following code assumes you're using Platform.runLater or similar code that makes the update run on the application thread.
public class UpdateSynchronizer {
private final List<Runnable> pendingUpdates = new ArrayList<>();
private boolean locked = false;
public void lock() {
if (locked) {
throw new IllegalStateException("double lock");
} else {
locked = true;
}
}
public void runUpdate(Runnable updater) {
if (updater == null) {
throw new IllegalArgumentException();
}
if (locked) {
pendingUpdates.add(updater);
} else {
updater.run();
}
}
public void unlock() {
for (Runnable r : pendingUpdates) {
try {
r.run();
} catch(Exception ex) {
ex.printStackTrace(); // print but ignore
}
}
pendingUpdates.clear();
locked = false;
}
}
If the last update always overwrites all the data from previous updates, simply keeping a single Runnable instead of a list of them would be more performant.
private final UpdateSynchronizer synchronizer = new UpdateSynchronizer();
// why did all the keywords start with uppercase letters (compile time error)
private void handleEvent(){
TableView.setRowFactory(new Callback<TableView<myModel>, TableRow<myModel>>(){
public TableRow<myModel> call(TableView<myModel> p) {
final TableRow row = new TableRow();
row.setOnDragDetected(new EventHandler<MouseEvent>(){
public void handle(){
synchronizer.lock();
//implement some kind of lock to prevent receiving data update
}
}
row.setOnMouseDragExited(new EventHandler<MouseDragEvent>(){
//release lock to accept update
synchronizer.unlock();
}
}
}
//this method is being called externally periodically
public void updateModel(myModel model){
synchronizer.runUpdate(() -> {
// this is just an assignment and won't have any side effects
// updates to the scene may only happen, if the model is accessed in some event handler or animation
this.model = model;
});
}
... that is after all its properties - including its value - are updated?
The use-case is a Task that
"collects" items into an ObservableList which is the result of the call method
the list should be set as value when the task is "finished", no matter if normally or cancelled
A snippet of the Task implementation (complete example at end):
#Override
protected ObservableList<Rectangle> call() throws Exception {
ObservableList<Rectangle> results = FXCollections.observableArrayList();
for (int i=0; i<=count; i++) {
// do fill list
//...
try {
Thread.sleep(200);
} catch (InterruptedException interrupted) {
if (isCancelled()) {
// do update value on cancelled
updateValue(results);
break;
}
}
}
return results;
}
It's intended usage:
bind the itemsProperty of a tableView to the valueProperty
unbind on "finished"
My approach was to listen to its state property and unbind on state changes to SUCCEEDED or CANCELLED. The former works just fine, the latter doesn't because at the time of receiving the cancelled, the value is not yet updated and consequently the items not set.
// working ... but when to unbind?
table.itemsProperty().bind(task.valueProperty());
task.stateProperty().addListener((src, ov, nv) -> {
if (Worker.State.SUCCEEDED == nv ) {
// this is fine because implementation in TaskCallable first
// updates the value (with the result it got from T call())
// then updates state
LOG.info("succeeded" + task.getValue());
table.itemsProperty().unbind();
} else if (Worker.State.CANCELLED == nv) {
LOG.info("receiving cancelled " + task.getValue());
// can't unbind here, value not yet updated
// table.itemsProperty().unbind();
}
});
So in case of cancelled, this leaves me with either a property that's still bound or an empty table. Feels like I'm doing something wrong. Or core Task impl is not as useful as expected? It would mean that we simply can't bind to the value property (nor any of the others like progress) due to being unable to safely cleanup (using table items here is just an example, because it's easy to see, same for all types of properties).
Question is, how to do it correctly/overcome the limitation?
The complete example:
public class TaskValueBinding extends Application {
private Parent createListPane() {
Task<ObservableList<Rectangle>> task = createListTask();
Thread thread = new Thread(task);
thread.setDaemon(true);
TableView<Rectangle> table = new TableView<>();
TableColumn<Rectangle, Double> xCol = new TableColumn<>("X");
xCol.setCellValueFactory(new PropertyValueFactory<>("x"));
TableColumn<Rectangle, Double> yCol = new TableColumn<>("Y");
yCol.setCellValueFactory(new PropertyValueFactory<>("y"));
table.getColumns().addAll(xCol, yCol);
// working ... but when to unbind?
table.itemsProperty().bind(task.valueProperty());
task.stateProperty().addListener((src, ov, nv) -> {
if (Worker.State.SUCCEEDED == nv ) {
// this is fine because implementation in TaskCallable first
// updates the value (with the result it got from T call())
// then updates state
LOG.info("succeeded" + task.getValue());
table.itemsProperty().unbind();
} else if (Worker.State.CANCELLED == nv) {
LOG.info("receiving cancelled " + task.getValue());
// can't unbind here, value not yet updated
// table.itemsProperty().unbind();
}
});
Label messageLabel = new Label("Message: ");
Label message = new Label();
message.textProperty().bind(task.messageProperty());
Label progressAsText = new Label();
Label progressLabel = new Label("Progress: ");
progressAsText.textProperty().bind(task.progressProperty().asString());
ProgressBar progress = new ProgressBar();
progress.progressProperty().bind(task.progressProperty());
Button start = new Button("Start");
start.setOnAction(e -> {
start.setDisable(true);
thread.start();
});
Button cancel = new Button("Cancel");
cancel.setOnAction(e -> task.cancel());
cancel.disableProperty().bind(task.runningProperty().not());
int row = 0;
GridPane grid = new GridPane();
grid.add(table, 0, row++, 20, 1);
grid.add(messageLabel, 0, row);
grid.add(message, 1, row++);
grid.add(progressLabel, 0, row);
grid.add(progressAsText, 1, row++);
grid.add(progress, 0, row++, 2, 1);
grid.add(start, 0, row);
grid.add(cancel, 1, row++);
return grid;
}
private Task<ObservableList<Rectangle>> createListTask() {
Task<ObservableList<Rectangle>> task = new Task<ObservableList<Rectangle>>() {
#Override
protected ObservableList<Rectangle> call() throws Exception {
updateMessage("Creating Rectangles ...");
ObservableList<Rectangle> results = FXCollections.observableArrayList();
String message = "finished";
int count = 10;
for (int i=0; i<=count; i++) {
if (isCancelled()) {
updateValue(results);
// when do we get here?
message = "cancelled";
break;
}
Rectangle r = new Rectangle(10, 10);
r.setX(10 * i);
results.add(r);
updateProgress(i, count);
// Now block the thread for a short time, but be sure
// to check the interrupted exception for cancellation!
try {
Thread.sleep(200);
} catch (InterruptedException interrupted) {
if (isCancelled()) {
updateValue(results);
message = "interrupted";
break;
}
}
}
updateMessage(message);
return results;
}
};
return task;
}
#Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createListPane()));
stage.setTitle(FXUtils.version());
stage.show();
}
public static void main(String[] args) {
launch(args);
}
#SuppressWarnings("unused")
private static final Logger LOG = Logger
.getLogger(TaskValueBinding.class.getName());
}
Cancelling the task immediately triggers an update of the state property. If canceled from the application thread Platfrom.runLater is not used for this purpose but the call of the cancel method updates the state immediately. This results in the state being changed before any updateValue call updates the value property using Platform.runLater.
Task is not designed to allow partial results so you need to implement custom logic to accommodate for this. Depending on your needs you could subclass Task to trigger a custom event when the task completes in any way.
public abstract class PartialResultTask<T> extends Task<T> {
// handler triggered after last change of value
private Runnable onDone;
public Runnable getOnDone() {
return onDone;
}
public void setOnDone(Runnable onDone) {
this.onDone = onDone;
}
protected abstract T calculateResult() throws Exception;
private void onDone() {
if (onDone != null) {
Platform.runLater(onDone);
}
}
#Override
protected final T call() throws Exception {
try {
T result = calculateResult();
updateValue(result); // update value to the final value
onDone();
return result;
} catch (Exception ex) {
onDone();
throw ex;
}
}
}
private PartialResultTask<ObservableList<Rectangle>> createListTask() {
PartialResultTask<ObservableList<Rectangle>> task = new PartialResultTask<ObservableList<Rectangle>>() {
#Override
protected ObservableList<Rectangle> calculateResult() throws Exception {updateMessage("Creating Rectangles ...");
ObservableList<Rectangle> results = FXCollections.observableArrayList();
int count = 10;
for (int i = 0; !isCancelled() && i <= count; i++) {
Rectangle r = new Rectangle(10, 10);
r.setX(10 * i);
results.add(r);
updateProgress(i, count);
// Now block the thread for a short time, but be sure
// to check the interrupted exception for cancellation!
try {
Thread.sleep(200);
} catch (InterruptedException interrupted) {
}
}
updateMessage(isCancelled() ? "canceled" : "finished");
return results;
}
};
return task;
}
task.setOnDone(() -> {
table.itemsProperty().unbind();
});
task.stateProperty().addListener((src, ov, nv) -> {
if (Worker.State.SUCCEEDED == nv) {
// this is fine because implementation in TaskCallable first
// updates the value (with the result it got from T call())
// then updates state
LOG.info("succeeded" + task.getValue());
} else if (Worker.State.CANCELLED == nv) {
LOG.info("receiving cancelled " + task.getValue());
}
});
I am using Simple.Data with SQL Server and I have multiple methods that are independent of each other. On a form I have multiple drop down lists that need to be populated and I think these can be populated asynchronously. I have a repository that returns List of entities.
From my Asp.Net website I call the methods on the repository one by one and bind them to the drop down lists here is a sample code
private void Initialize()
{
LoadTechnologies();
LoadInstallationTypes();
LoadProvinces();
LoadYears();
}
private void LoadTechnologies()
{
ddlTechnologies.DataSource = _GizRepository.GetTechnologies();
ddlTechnologies.DataValueField = "Name";
ddlTechnologies.DataTextField = "Name";
ddlTechnologies.Items.Insert(0, new ListItem("All", "-1"));
ddlTechnologies.DataBind();
}
private void LoadInstallationTypes()
{
ddlInstallationType.DataSource = _GizRepository.GetInstallationTypes();
ddlInstallationType.DataValueField = "Type";
ddlInstallationType.DataTextField = "Type";
ddlInstallationType.Items.Insert(0, new ListItem("Any", "-1"));
ddlInstallationType.DataBind();
}
private void LoadProvinces()
{
ddlProvinces.DataSource = _GizRepository.GetProvinces();
ddlProvinces.DataValueField = "Name";
ddlProvinces.DataTextField = "Name";
ddlProvinces.Items.Insert(0, new ListItem("All", "-1"));
ddlProvinces.DataBind();
}
private void LoadYears()
{
ddlYearFrom.DataSource = _GizRepository.GetYears();
ddlYearFrom.DataValueField = "Year";
ddlYearFrom.DataTextField = "Year";
ddlYearFrom.DataBind();
ddlYearTo.DataSource = _GizRepository.GetYears();
ddlYearTo.DataValueField = "Year";
ddlYearTo.DataTextField = "Year";
ddlYearTo.DataBind();
}
You can see from the code above that all I am doing is fetching some lists from the repository and bind them to the drop downs. I want to execute these methods asynchronously instead of synchronously, Kindly guide how it can be done?
Use async/await but don't return a Task from each routine. The effect is that they run concurrently all awaiting on their own io and then complete on the UI thread.
private void Initialize()
{
LoadTechnologies();
LoadInstallationTypes();
LoadProvinces();
LoadYears();
}
// Note that LoadTechnologies will return as soon as it is
// called. The part after the await will be scheduled on
// the UI thread after the task completes with the data
private async Task LoadTechnologies()
{
ddlTechnologies.Datasource =
await Task.Run(()=>GizRepository.GetTechnologies());
ddlTechnologies.DataValueField = "Name";
ddlTechnologies.DataTextField = "Name";
ddlTechnologies.Items.Insert(0, new ListItem("All", "-1"));
ddlTechnologies.DataBind();
}
private async Task LoadInstallationTypes()
{
...
}
...
}
At the moment there's no way to make Simple.Data do proper asynchronous database calls. Work is starting on version 2 next week, and the first new feature to be added is proper asynchronous operations for those back ends - such as SQL Server - where the ADO provider has asynchronous methods.
I have run into this problem across multiple programming languages and I was just wondering what the best way to handle it is.
I have three method calls that fire off asynchronously. Each one has a callback. I want to do something only when all three callbacks have completed.
What is the best way to code this? I usually end up with all these public bool flags and as you add more calls the code gets more convoluted.
Coming from C#, I would probably use WaitHandle.WaitAll. You can create an array of ManualResetEvent objects (one for each task to be completed), and pass that array to WaitAll. The threaded tasks will get one ManualResetEvent object each, and call the Set method when they are ready. WaitAll will block the calling thread until all tasks are done. I'll give a C# code example:
private void SpawnWorkers()
{
ManualResetEvent[] resetEvents = new[] {
new ManualResetEvent(false),
new ManualResetEvent(false)
};
// spawn the workers from a separate thread, so that
// the WaitAll call does not block the main thread
ThreadPool.QueueUserWorkItem((state) =>
{
ThreadPool.QueueUserWorkItem(Worker1, resetEvents[0]);
ThreadPool.QueueUserWorkItem(Worker2, resetEvents[1]);
WaitHandle.WaitAll(resetEvents);
this.BeginInvoke(new Action(AllTasksAreDone));
});
}
private void AllTasksAreDone()
{
// OK, all are done, act accordingly
}
private void Worker1(object state)
{
// do work, and then signal the waiting thread
((ManualResetEvent) state).Set();
}
private void Worker2(object state)
{
// do work, and then signal the waiting thread
((ManualResetEvent)state).Set();
}
Note that the AllTasksAreDone method will execute on the thread pool thread that was used to spawn the workers, and not on the main thread... I assume that many other languages have similar constructs.
If you really only want to wait for all to finish:
Create volatile counter
Synchronize access to counter
Increase counter on start
Decrease on callback fired
Wait for counter to reach 0
Use a semaphore.
Futures are very easy to use. Futures look like normal functions, except that they execute asynch.
The classes:
public struct FutureResult<T>
{
public T Value;
public Exception Error;
}
public class Future<T>
{
public delegate R FutureDelegate<R>();
public Future(FutureDelegate<T> del)
{
_del = del;
_result = del.BeginInvoke(null, null);
}
private FutureDelegate<T> _del;
private IAsyncResult _result;
private T _persistedValue;
private bool _hasValue = false;
private T Value
{
get
{
if (!_hasValue)
{
if (!_result.IsCompleted)
_result.AsyncWaitHandle.WaitOne();
_persistedValue = _del.EndInvoke(_result);
_hasValue = true;
}
return _persistedValue;
}
}
public static implicit operator T(Future<T> f)
{
return f.Value;
}
}
Here I use futures to simulate a deadlock:
void SimulateDeadlock()
{
Future> deadlockFuture1 = new Future>(() =>
{
try
{
new SystemData(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString)
.SimulateDeadlock1(new DateTime(2000, 1, 1, 0, 0, 2));
return new FutureResult { Value = true };
}
catch (Exception ex)
{
return new FutureResult { Value = false, Error = ex };
}
});
Future> deadlockFuture2 = new Future>(() =>
{
try
{
new SystemData(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString)
.SimulateDeadlock2(new DateTime(2000, 1, 1, 0, 0, 2));
return new FutureResult { Value = true };
}
catch (Exception ex)
{
return new FutureResult { Value = false, Error = ex };
}
});
FutureResult result1 = deadlockFuture1;
FutureResult result2 = deadlockFuture2;
if (result1.Error != null)
{
if (result1.Error is SqlException && ((SqlException)result1.Error).Number == 1205)
Console.WriteLine("Deadlock!");
else
Console.WriteLine(result1.Error.ToString());
}
else if (result2.Error != null)
{
if (result2.Error is SqlException && ((SqlException)result2.Error).Number == 1205)
Console.WriteLine("Deadlock!");
else
Console.WriteLine(result2.Error.ToString());
}
}
For those using JavaScript, consider using the pattern discussed at this Stackoverflow question:
javascript: execute a bunch of asynchronous method with one callback