I am trying to update a large (~150,000 line) Java/Eclipse program from 2009 that has several threads, and communicates with a TCP-IP telescope. I wrote new code to do the communications, and that all works fine when separately tested. This is on a Mac - the original worked on Mac OSX 10.6 and nothing later - I'm writing this for current Mac OS 12.xx
In the overall program, there is a thread that receives mouse clicks from the GUI and initiates operation of a thread with runs the communications code. The communications thread stays alive, using parameters passed to it to determine which communication function to execute.
Here's some of the code:
class ActualTask {
ActualTask () {
// PRAA Dec 7 2021
System.out.println("What thread are we in? it's: "+ Thread.currentThread().getName());
while (true) // this is true so we can keep reusing this task!
{
// PRAA Dec 7 2021
//System.out.println("What thread are we in? it's: "+ Thread.currentThread().getName());
if (running)
{
// PRAA Dec 7 2021
System.out.println("Just before call to run() - What thread are we in? it's: "+ Thread.currentThread().getName());
run();
// PRAA Dec 7 2021
System.out.println("What thread are we in? it's: "+ Thread.currentThread().getName());
running = false;
}
}
}
// ------------------------------------
void run()
{
done = false;
successful = true;
telescopeException = null;
// PRAA Dec 7 2021
System.out.println("In run() - thread is: "+ Thread.currentThread().getName());
try
{ // *** execute the telescope task ***
TelescopeGlobals.telescopeProgressTaskData.setBackgroundColor(Color.red); // red when active
telescopeTask.execute();
done = true;
TelescopeGlobals.telescopeProgressTaskData.setBackgroundColor(Color.white); // white when NOT active
}
catch (TelescopeException te)
{
// Clear progress bar before throwing up dialog
TelescopeGlobals.telescopeProgressTaskData.setBackgroundColor(Color.white); // white when NOT active
TelescopeGlobals.telescopeProgressTaskData.clear();
done = true;
successful = false;
telescopeException = te;
Reporting.selctiveAlert(te.getMessage() + "\n" + te.getWhereExceptionOccured());
TelescopeGlobals.telescopeProgressTaskData.setText1("Error: " + te.getMessage());
TelescopeGlobals.telescopeProgressTaskData.setText2("Where: " + te.getWhereExceptionOccured());
}
done = true;
}
}
When I am in "debug" mode, and I single-step through the communications code, things usually execute properly - however, when I hit "Run", things don't go so well -
the first call works ok
the second call appears to do nothing - that is, it doesn't seem to be executing, and none of my print statements print
subsequent calls only print an error message saying the previous task has not completed.
So I'm wondering - what is the difference between the "run" and "debug" modes - why would one work and the other behave differently - and
Does all of the "SwingWorker" stuff from 2009 still work?
Should creating the communications thread be done differently? It is just created once, as shown in the code snippet below:
// Static member above of HighLevelTaskWorker makes sure that one command is dispatched to the telescope at a time.
class HighLevelTaskWorker { // SwingWorker wrapper class
private lib.SwingWorker worker = null;
private boolean done;
private boolean successful;
private TelescopeException telescopeException;
private boolean running;
private TelescopeTask telescopeTask;
public HighLevelTaskWorker()
{
}
public void start(TelescopeTask telescopeTask) {
this.telescopeTask = telescopeTask;
// PRAA Dec 7 2021
System.out.println("What thread are we in? it's: "+ Thread.currentThread().getName());
done = false;
successful = false;
telescopeException = null;
running = true;
if (worker == null) // no need to create this tread over and over again, think of all that Garbage Collecting and tread creation!
{
worker = new lib.SwingWorker() {
public Object construct() {
return new ActualTask();
}
};
worker.start();
}
}
Thanks so much for any help !!!
Related
This question already has answers here:
Java executors: how to be notified, without blocking, when a task completes?
(12 answers)
Closed 5 years ago.
Hello i am generally new to java and working on Minecraft Plugins to get started.
Here is my problem. I am trying to call this method on the main server thread and get the return value.
Here is what i am trying to achieve.
private String FetchEntry(String TableName, String KeyID, String ColumnName) {
String value = "NOTHING";
Bukkit.getServer().getScheduler().scheduleAsyncDelayedTask(LGCore.plugin, new Runnable() {
#Override
public void run() {
try {
ResultSet resultSet;
resultSet = GetConnection().createStatement().executeQuery("SELECT " + ColumnName + " FROM " + TableName + " WHERE IdKey='" + KeyID + "';");
resultSet.first();
String returnvalue = resultSet.getString(1);
//Here i would like to set value to returnvalue and return it
} catch (SQLException e) {
e.printStackTrace();
}
}
});
return value;
}
You seem to be calling a method that schedules an asynchronous task.
But an asynchronous task directly returning a value without blocking is sort of like an oxymoron: If it would directly return a value, it would be a synchronous operation.
The idea of asynchronous operations is that you run the operation to retrieve the result later when it's ready, but your main thread continues to run.
So you need to store the result of your asynchronous task in a place that's accessible by your main thread when it's ready.
I'm not familiar with the Minecraft code base, but I hope this helps anyway.
So, I have a non-looping Thread that I want to stop. I searched the internet and did not find a solution without creating a looping Thread.
The Thread requests information from a web server and displays the results in a JList. It does not loop forever. The reason why I made this function a Thread is because it takes about 1-5 minutes depending on how much information are send from the web server and I want to continue working in the application without it being blocked by the request. The Thread looks like this:
public class Search extends Thread implements Runnable{
#Override
public void run(){
requestToWebServer(); //10-20sec
receiveInformation(); //10-20sec
handleResponse(); //1-4min
addDataToJList(); //5sec
}
}
Now my problem is that I do not see any way to stop this Thread from running completely. I don't want to use the deprecated method Thread.stop.
Edit:
Complete code in run method:
public void run(){
try{
log.info(Languages.getString("SearchFrame.2") + this.query); //$NON-NLS-1$
String resp = ConnectionUtils.request("http://hdfilme.tv/movie/search?key=" //$NON-NLS-1$
+ this.query.replaceAll(" ", "+")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
Matcher movie_img_matcher = MOVIE_IMG_PATTERN.matcher(resp);
Matcher movie_stream_matcher = MOVIE_STREAM_PATTERN.matcher(resp);
log.info(Languages.getString("SearchFrame.4")); //$NON-NLS-1$
while (movie_img_matcher.find()) {
img_src.add(new URL(movie_img_matcher.group(1)));
names.add(movie_img_matcher.group(2));
}
log.info(Languages.getString("SearchFrame.5") + img_src.size() + Languages.getString("SearchFrame.6")); //$NON-NLS-1$ //$NON-NLS-2$
log.info(Languages.getString("SearchFrame.7")); //$NON-NLS-1$
while (movie_stream_matcher.find() && mov_src.size() < img_src.size()) {
mov_src.add(new URL(movie_stream_matcher.group(1) + "stream")); //$NON-NLS-1$
}
log.info(Languages.getString("SearchFrame.5") + mov_src.size() + Languages.getString("SearchFrame.8")); //$NON-NLS-1$ //$NON-NLS-2$
log.info(Languages.getString("SearchFrame.9")); //$NON-NLS-1$
for (int i = 0; i < mov_src.size(); i++) {
log.debug(Languages.getString("SearchFrame.10")); //$NON-NLS-1$
String response = ConnectionUtils.request(mov_src.get(i).toString());
ConnectionUtils.getLastPage();
Matcher movie_link_matcher = MOVIE_LINK_PATTERN.matcher(response);
log.debug(Languages.getString("SearchFrame.11")); //$NON-NLS-1$
if (movie_link_matcher.find()) {
res.add(movie_link_matcher.group(2));
con = getCon(new URL(movie_link_matcher.group(1).replaceAll("\\\\/", "/")), "HEAD");
log.debug(Languages.getString("SearchFrame.12")); //$NON-NLS-1$
last_modified.add(con.getHeaderField("Last-Modified")); //$NON-NLS-1$
sizes.add(i, con.getContentLengthLong());
}
if(Options.getString("DefaultDownload").equals("0")){
dirs.add(i, System.getProperty("user.home") + "\\Videos"); //$NON-NLS-1$ //$NON-NLS-2$
} else {
dirs.add(i, Options.getString("DefaultDownload"));
}
}
log.debug(Languages.getString("SearchFrame.13")); //$NON-NLS-1$
for(int i = 0; i < mov_src.size(); i++){
try{
model.addElement(new Movie(mov_src.get(i), img_src.get(i), names.get(i), res.get(i), dirs.get(i), last_modified.get(i), sizes.get(i)));
} catch(IndexOutOfBoundsException ex){
log.info(ex);
}
}
} catch(Exception ex){
log.error(ex);
}
}
You will have to insert in your code into each loop iteration and in some other places if you wish a check with method invocation isInterrupted() or interrupted() and if the thread has been interrupted just return from your thread. In your parent thread you need to invoke interrupt() method on the thread that you want to stop. Then next time your child-thread will check if it was interrupted it will know to return. Please read more on mentioned methods in java doc for class Thread. The only safe way to kill thread is to ask the Thread itself to stop. Any other way is inherently dangerous. That is why method stop() has been depricated
How Can I get active time of Thread for which it was actually in running state. Minus all the Waiting and Sleeping time.
I didn't seem to find anything in Thread API that gives me desired results.
If not exact code any ideas or Pseudo Codes would be great start.
Thanks
Thanks assylias
The ThreadMXBean worked for me.. Here is sample code of what I did.
#Override
public void run() {
System.out.println(Thread.currentThread().getName());
try {
for(int i = 999999999; i > 0; i--){}
Thread.sleep(5000);
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
long threadCpuTime = threadBean.getCurrentThreadCpuTime();
System.out.println(Thread.currentThread().getName() + " :: " + threadCpuTime);
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
I Put up a sleep of 5 seconds just to check if it was added to CPU time. It wasn't added. Also I put up empty for loop so that processing takes some time.
Here's Output
Thread-1 :: 15600200
Thread-4 :: 15700100
Thread-3 :: 15600100
Thread-0 :: 15500100
Thread-2 :: 0
Dear All I have this type of code:
public class Testimplements Runnable {
public static void main(String[] args) {
InTheLoop l= new InTheLoop();
Thread th = new Thread(l);
th.start();
th.interrupt();
}
#Override
public void run() {
int count = 0;
for (Integer i = 0; i <=10000000000000000000; i++) {
}
}
}
I know there is ways to kill thread. For instance:
// Example 1
if (Thread.interrupted()){
return;
}
// Example 2
if(flag){ // volatile
return;
}
but can't I kill the thread without if statement?
You can use the stop() method if you really have to, but be aware that it is inherently unsafe and deprecated.
See http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html for details.
As far as I know you have to implement the interruption policy for your thread yourself, how it handles the interrupt call and when it stops etc.
See: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Instead of thread better use ExecutorService for more control on threads.
Read more in oracle documentation and here is tutorial
This subject is very important and I could not find any clear answer for That so I write a sample code with OOP form to explain that
import threading
import time
import tkinter as tk
class A(tk.Tk):
def __init__(self ,*args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.count = 0
self._running = True
self.Do = 0
A.Run(self)
def Thread_Terminate(self): # a method for killing the Thread
self._running =False
self.T.join()
self.Btn2.config (state='normal')
self.Btn1.config (state='disabled')
def Thread_Restart(self): # a thred for Start and Restart the thread
self.Btn1.config (state='normal')
self._running = True
self.T = threading.Thread(target=self.Core) # define Thread
if (self.T.is_alive() != True): # Cheak the Thread is that alive
self.T.start()
self.Btn2.config (state='disabled')
def Window (self):
self.title(" Graph ")
self.geometry("300x300+100+100")
self.resizable(width=False, height=False)
self.Lbl1 = Label(self,text = '0' ,font=('Times', -50, 'bold'), fg='Blue')
self.Lbl1.pack()
self.Lbl1.place(x=130, y=30 )
self.Btn1 = Button(self,text= 'Thread OFF',width=25,command = self.Thread_Terminate)
self.Btn1.pack()
self.Btn1.place(x=50,y=100)
self.Btn1 ['state'] = 'disable'
self.Btn2 = Button(self, text='Thread ON', width=25, command=self.Thread_Restart)
self.Btn2.pack()
self.Btn2.place(x=50, y=140)
self.Ent1 = Entry(self, width = 30, fg='Blue')
self.Ent1.pack()
self.Ent1.place(x=50, y=180)
def Core(self): # this method is the thread Method
self.count = 0
i = self.Ent1.get()
if (i==''):
i='10'
while (self._running and self.count<int(i)):
self.count +=1
self.Lbl1.config(text=str(self.count))
print(str (self.count)+'Thread Is ON')
time.sleep(0.5)
def Run(self):
A.Window(self)
self.mainloop()
if __name__ == "__main__":
Obj1 = A()
Im working on a elevator simulator, in wich i have to simulate the work of 4 elevators in a building. Well, at first i thought it was easy, 4 threads and its all good. but im running into trouble because my threads won't run at the same time, even with infinite cycles only one thread runs at a time.
#Override
public void run() {
while (true)
{
int i = rand.nextInt(p1.getNFloors());
building.getFloors().get(i).putPersons();
System.out.println(building.toString());
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(Relogio.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
and on a seperate thread :
#Override
public void run() {
while (true)
{
for (int i = 0; i < building.getFloors().size(); i++)
{
if (building.getFloors().get(i).getPersons().size() != 0)
{
building.getFloors().get(i).callElevator(); //this should call 1 elevator
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(Thread1.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
and i have 4 instances of this thread running (therefor i have 4 elevators)
the problem is: only 1 thread runs at a time, so only 1 elevator at a time.
btw, the callElevator method gets the elevator from an arrayList in wich i have 4 elevators stored. the condition that needs to be met is if the elevator is stopped he can be called.
the way i start the threads:
the first thread (the one that puts people in the floors): thread.start();
and after that , i initialize 4 instances of the thread that calls the elevators.
so it looks like this:
Simulator s1 = new Simulator();
ElevatorThread et1 = new ElevatorThread();
ElevatorThread et2 = new ElevatorThread();
ElevatorThread et3 = new ElevatorThread();
ElevatorThread et4 = new ElevatorThread();
s1.start();
et1.start();
et2.start();
et3.start();
et4.start();
both threads extends Thread.
any tips?