Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
class A {
synchronized void bar(B b) {
Thread t = Thread.currentThread();
System.out.println("Entered In A "+t);
try{
Thread.sleep(1000);
}
catch(Exception e) {
}
System.out.println("A trying to enter B");
b.last();
}
synchronized void last() {
System.out.println("Inside A last");
}
}
class B {
synchronized void bar(A a) {
Thread t = Thread.currentThread();
System.out.println("Entered In B "+t);
try{
Thread.sleep(1000);
}
catch(Exception e) {
}
System.out.println("B trying to enter A");
a.last();
}
synchronized void last() {
System.out.println("Inside B last");
}
}
class Main {
public static void main(String[] args) {
A a = new A();
B b = new B();
// Thread t1 = new Thread(){
// public void run() {
// a.bar(b);
// }
// };
Thread t2 = new Thread() {
public void run() {
b.bar(a);
}
};
System.out.println("Initialization :");
// t1.start();
a.bar(b);
t2.start();
}
}
Your code doesn't start the t2 thread until after the a.bar(b) call has returned. It never tries to call both bar() methods concurrently.
Try switching those last two lines: Call t2.start() first, and then call a.bar(b).
If that doesn't work, then maybe try:
t2.start();
try { sleep(100); } catch {...}
a.bar(b);
The short sleep() call in the main thread will give the t2 thread more time to start up and actually enter the b.bar(a) call.
Related
I'm doing a desktop application and I'm performing a heavy task in background. I want a progress bar to be updated. My program works and I can see the progress bar here isn't my problem. My problem is that I use 2 tasks that I run in 2 thread in order to make both the update of the progress bar and the heavy task. My question is : Is there a better way to do in oder to avoid the error "Exception in thread "Thread-5" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-5".
Of course I already check on Internet and I always find : better use Platform.runLater. Ok but in both new thread I need attribute of my class, eg I can't access for example "this.myAttribute" when I use Platform.runLater((new Runnable()...)). Is RunLater the solution and I can't see it ?
Here is a bunch of code, the method setConnection is called in JavaFX thread, and I create 2 other. One for progressbar, the other for my task :
#FXML
private void setConnection() {
try {
this.onOffButton.setSelected(false);
if (!this.hubModel.isConnected()) {
this.progressBar.progressProperty().unbind();
#SuppressWarnings("unchecked")
OperationTask progressBarOperationTask = new OperationTask(this) {
#Override
public Void call() {
HubController hubController = (HubController) this.getHubController();
hubController.getProgressBar().setVisible(true);
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(25);
} catch (InterruptedException e) {
Thread.interrupted();
break;
}
updateProgress(i + 1, 100);
}
hubController.getProgressBar().setVisible(false);
return null;
}
};
this.progressBar.progressProperty().bind(progressBarOperationTask.progressProperty());
Thread timeThread = new Thread(progressBarOperationTask);
timeThread.setDaemon(true);
timeThread.start();
}
#SuppressWarnings("unchecked")
OperationTask connectionOperationTask = new OperationTask(this) {
#Override
protected Object call() throws Exception {
HubController hubController = (HubController) this.getHubController();
if (hubController.getUserID().getText().equals("") || hubController.getUserPW().getText().equals("")) {
hubController.getCommentBottom().setText("Please enter a user name and a password.");
hubController.getOnOffButton().setSelected(false);
} else {
hubController.getHubModel().setIdUser(hubController.getUserID().getText());
hubController.getHubModel().setPwUser(hubController.getUserPW().getText());
String comment = hubController.getHubModel().setConnection();
if (!comment.equals("Connection established.")) {
hubController.getOnOffButton().setSelected(false);
}
if (hubController.getHubModel().isConnected()) {
hubController.getConnectionStatus().setText("Connected");
hubController.getConnectionStatus().setStyle("-fx-font-weight: bold");
String commentProject = hubController.getHubModel().getAllProjects();
if (commentProject.equals("")) {
TextFields.bindAutoCompletion(hubController.getCloneAndMoveController().getNewProjectNameTextField(), hubController.getHubModel().getProjectsList());
} else {
comment = commentProject;
}
hubController.getOnOffButton().setSelected(true);
} else {
hubController.getConnectionStatus().setText("Not connected");
hubController.getConnectionStatus().setStyle("-fx-font-weight: regular");
}
hubController.getCommentBottom().setText(comment);
}
return null;
}
};
Thread connectionThread = new Thread(connectionOperationTask);
connectionThread.setDaemon(true);
connectionThread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
Moreover if you see something that could be improved, I would appreciate (I'm new with java)
Thank you.
You can access your object from Platform.runLater(). New Runnable which you create for it has access to this instance of your object. See in an example:
private String myAttribute = "hello";
#Override
public void randomMethod() {
//...
Platform.runLater(new Runnable() {
#Override
public void run() {
System.out.println(myAttribute);
}
});
}
I am trying to learn basic concept of Multi Threading.
Why my ping pong program prints only Ping0 & Pong0, Why notify() does not start the Ping Thread which is in Wait state?
public class PingPong implements Runnable {
String word;
public PingPong(String word) {
this.word = word;
}
public void run() {
synchronized (this) {
for (int i = 0; i < 10; i++) {
System.out.println(word + i);
try {
wait();
notifyAll();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
public static void main(String[] args) {
Runnable p1 = new PingPong("ping");
Thread t1 = new Thread(p1);
t1.start();
Runnable p2 = new PingPong("pong");
Thread t2 = new Thread(p2);
t2.start();
}
}
Output
ping0
pong0
I tried removing wait() and it's printing ping pong till the end of loop. but is this guaranteed that it will print in sequence?
Why wait() followed by notify() does not ask the ping1 thread to start execution?
If you see the jstack, you can see thread-0 and thread-1 are waiting for different lock. That's because your p1 and p2 are different objects, so when you use synchronized (this), they are not competing for the same lock, so notify this way won't work. try use another object as the lock.
wait need to run after notify. As when both threads go into waiting stat, no other threads can notify them.
try this code:
String word;
Object a;
public PingPong(String word, Object a) {
this.word = word;
this.a = a;
}
public void run() {
synchronized (a) {
for (int i = 0; i < 10; i++) {
System.out.println(word + i);
try {
a.notifyAll();
a.wait();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Runnable p1 = new PingPong("ping", a);
Thread t1 = new Thread(p1);
t1.start();
Runnable p2 = new PingPong("pong", a);
Thread t2 = new Thread(p2);
t2.start();
}
Here is a similar solution using Thread Pool Executors:
public class PingPong implements Runnable {
String word;
Lock lock;
public PingPong(String word, Lock lock) {
this.word = word;
this.lock = lock;
}
#Override
public void run() {
while(true){
System.out.println("Received : " + word);
lock.notifyAll();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService ex = Executors.newFixedThreadPool(2);
Lock lock = new ReentrantLock();
while(true){
ex.submit(new PingPong("ping", lock));
ex.submit(new PingPong("pong", lock));
}
}
}
Below solution based on:
Java internal API
order of execution
public class Test {
public static void main(String[] args) {
SynchronousQueue<String> queue = new SynchronousQueue<>();
Thread ping = new Thread(new Task(queue, "ping", "ping"));
ping.setName("ping thread");
ping.start();
Thread pong = new Thread(new Task(queue, "pong", "ping"));
pong.setName("pong thread");
pong.start();
}
private static class Task implements Runnable {
private SynchronousQueue<String> queue;
private String command;
private String step;
Task(SynchronousQueue<String> queue, String command, String step) {
this.queue = queue;
this.command = command;
this.step = step;
}
#Override
public void run() {
try {
if (command.equals(step)) {
doCommandAndWaitRepeatedly();
} else {
waitAndDoCommandRepeatedly();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private void doCommandAndWaitRepeatedly() throws InterruptedException {
while (true) {
queue.offer(command, 1, TimeUnit.SECONDS);
Thread.sleep(500);
System.out.println(Thread.currentThread().getName() + ":" + queue.poll(1, TimeUnit.SECONDS));
}
}
private void waitAndDoCommandRepeatedly() throws InterruptedException {
while (true) {
System.out.println(Thread.currentThread().getName() + ":" + queue.poll(1, TimeUnit.SECONDS));
Thread.sleep(500);
queue.offer(command, 1, TimeUnit.SECONDS);
}
}
}
}
class Ping extends Thread
{
public void run()
{
for(int i=1;i<=5;i++)
{
System.out.println("PING");
try{
sleep(2000);
} catch(Exception e){}
}
}
}
class Pong extends Thread
{
public void run()
{
for (int i=1;i<=5;i++)
{
System.out.println("PONG");
try{
sleep(2000);
} catch(Exception e){}
}
}
}
public class PingPong
{
public static void main(String... args) throws Exception
{
Ping p1=new Ping();
Pong p2=new Pong();
p1.start();
Thread.sleep(1000); //super important for proper sequence
p2.start();
p1.join();
}
}
I am trying to run a thread in background with while(true) condition, and not using any join after the thread so that it continue running the main thread. But what I am observing is only while loop is running and it is not switching to main thread. please help me find the issue. This is Groovy code.
public static void main(args) {
Thread.start {
while (true) {
long sleepMillis = 2000
System.out.println("inside async block")
Thread.sleep(sleepMillis)
}
}
//main func code goes here
}
Please give me pointers to the issue.
Here You go:
public class Lol {
public static void main(String[] args) {
def t = new Thread(new Runnable() {
public void run() {
while(true) {
println 'lol'
Thread.sleep(500)
}
}
}).start()
println 'other'
}
}
I would like to know if the following method is correct or not.
I've producer and consumer thread that work on a common BlockingQueue.
The producer is a sniffer thread so it will stop automatically,but fot the consumer i think to terminate with a loop on status (alive/dead) of producer thread. Any suggestions? Thanks
-)From the Main thread:
ArrayBlockingQueue<PcapPacket> queue = new ArrayBlockingQueue<>();
Producer p = new Producer(queue);
Thread t1 =new Thread(p);
t1.start();
Consumer c = new Consumer(queue,t1);
new Thread(c).start();
-)Producer
public void run() {
public void nextPacket(PcapPacket packet, String user) {
try {
queue.put(packet);
} catch (InterruptedException ex) {
}
-) Consumer
public void run() {
while(producer.isAlive()){
try {
//Thread.sleep(50);
packet=queue.take();
Polling producer's status is sub-optimal.
Preferred approach is to make producer, during producer exit, put some 'poison pill' into queue, and for consumer to end it's loop as soon as it have received that pill:
class Producer implements Runnable {
static final Object TIME_TO_STOP = new Object();
private final BlockingQueue<Object> q;
Producer(BlockingQueue<Object> q) {
this.q = q;
}
#Override
public void run() {
try {
while (true) {
q.put(readNextPacket());
}
} finally {
// exception happened
try {
q.put(TIME_TO_STOP);
} catch (InterruptedException e) {
// somehow log failure to stop properly
}
}
}
}
class Consumer implements Runnable {
private final BlockingQueue<Object> q;
Consumer(BlockingQueue<Object> q) {
this.q = q;
}
#Override
public void run() {
while (true) {
Object packet = q.take();
if (packet == Producer.TIME_TO_STOP) {
break;
}
// process packet
}
}
}
I have a TableView associated with some data, and once i hit a run button i perform some processing on that data. Each row of data is handled in a seperate thread, and while those threads are running i want a ProgressInducator to replace the table within its vbox.
In the attached code:
If I stop where is says "WORKS IF STOP HERE" - table is replaced with pi.
If I continue waiting for the threads to join - no replacing.
What am I missing?
runButton.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent e) {
List<Thread> threadList = new ArrayList<Thread>();
int threadCounter = 0;
final ProgressIndicator pi = new ProgressIndicator(threadCounter);
vbox.getChildren().clear();
vbox.getChildren().addAll(pi);
for (ProductInTable product : data) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try
{
product.calculate();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
threadList.add(thread);
thread.start();
}
int x = threadList.size();
/** WORKS IF STOP HERE **/
// wait for all threads to end
for (Thread t : threadList) {
try {
t.join();
threadCounter++;
pi.setProgress(threadCounter / x);
} catch (InterruptedException interE) {
interE.printStackTrace();
}
}
/** DOESNT WORKS IF STOP HERE **/
Thread.join() blocks execution until the thread is completed. Since you are calling this on the FX Application Thread, you block that thread until all your worker threads finish. This means the UI is unable to update until those threads are complete.
A better approach is probably to represent each computation with a task, and update a counter of complete tasks back on the FX Application Thread using setOnSucceeded. Something like:
runButton.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent e) {
final ProgressIndicator pi = new ProgressIndicator(threadCounter);
vbox.getChildren().clear();
vbox.getChildren().addAll(pi);
final int numTasks = data.size();
// only access from FX Application thread:
final IntegerProperty completedTaskCount = new SimpleIntegerProperty(0);
pi.progressProperty().bind(completedTaskCount.divide(1.0*numTasks));
completedTaskCount.addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> obs, Number oldValue, Number newValue) {
if (newValue.intValue() >= numTasks) {
// hide progress indicator and show table..
}
}
});
for (final ProductInTable product : data) {
Task<Void> task = new Task<Void>() {
#Override
public Void call() {
try
{
product.calculate();
} catch (IOException ioe) {
ioe.printStackTrace();
}
return null ;
}
});
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
completedTaskCount.set(completedTaskCount.get()+1);
}
});
new Thread(task).start();
}
}
});
If you potentially have a large number of items here, you should use some kind of ExecutorService instead to avoid creating too many threads:
ExecutorService exec = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()); // for example...
and then replace
new Thread(task).start();
with
exec.submit(task);