Kill thread when it called twice - java

I made thread that send String back to main thread periodically.
and I put this thread on some function.
When I press some button, than function will be called and do the work.
The problem is when I press that button twice.
That two threads are sending their String to main thread.
(They do the exactly same thing, but different string.)
But I don't need the first thread when thread started again.
Is their any way to kill the first thread?
here's the code.
private void speller_textbox(final String string){
final int strlen = string.length();
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
int cursor= 0;
while(cursor != strlen){
try{
Message message = Message.obtain();
message.obj = string.subSequence(0,cursor);
txt_handler.sendMessage(message);
cursor++;
Thread.sleep(100);
}catch (Exception e){
e.printStackTrace();
}
}
}
});
thread.start();
}
txt_handler is on the main thread.

First replace your working thread from method. Than:
private Thread workingThread;
//.....
private void speller_textbox(final String string){
if (workingThread != null && workingThread.isAlive()) {
workingThread.interrupt();
}
final int strlen = string.length();
workingThread = new Thread(new Runnable() {
#Override
public void run() {
int cursor= 0;
while(cursor != strlen){
try{
Message message = Message.obtain();
message.obj = string.subSequence(0,cursor);
txt_handler.sendMessage(message);
cursor++;
Thread.sleep(100);
}catch (Exception e){
e.printStackTrace();
}
}
}
});
thread.start();
}

Related

Thread issue in javafx. Multiple thread are created

I have program with javafx and want to refresh list's with new data when other user's insert data. So program to have real-time data. Problems is with thread i created. Every time i open a view it's create a new thread and have multiple notifications instead of one. I tried to extend class with Thread and with implementing Runnable but i had no success.
On method initialize i have code where i create a runnable and set it to thread.
int i = 0;
Runnable br = new Runnable() {
#Override
public void run() {
while (i < i + 1) {
try {
Thread.sleep(1000);
if (count_pacient_number != pjc.getPacientForDoctor(doctor_login).size()) {
Platform.runLater(new Runnable() {
#Override
public void run() {
emf.getCache().evictAll();
pacientList.clear();
patientList();
count_pacient_number = pjc.getPacientForDoctor(doctor_login).size();
}
});
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
};
// private Thread thread = null; is created on start of class
thread = new Thread(br);
thread.setDaemon(true);
thread.start();

Java async problems

So my code works just the way I want it the only issue I'm having is this.. Basically I am having a main class which controls gates on a railroad track, when a train is approaching or crossing the track from either 1 of two tracks the gates should close. The only issue I'm having is the statements for when a gate opens or closes spam like 3-5 times everytime it does something so if the gate is closing it will go..
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closed
I'm wondering why this is occuring, here is my code for the Gate class and Main class
public class Gate {
private boolean isClosed = false;
private boolean closing = false;
private boolean opening = false;
public Gate(){
}
public void close(){
if(!(isClosing() == true)){
Runnable task = new Runnable() {
public void run() {
try {
setClosing(true);
setOpening(false);
System.out.println("GATE: Closing");
Thread.sleep(400);
System.out.println("GATE: Closed");
setClosed(true);
setClosing(false);
}catch(Exception ex){
}
}
};
new Thread(task, "closeThread").start();
}
}
public void open(){
if(!(isOpening() == true)){
Runnable task = new Runnable() {
public void run() {
try {
setOpening(true);
System.out.println("GATE: Opening");
Thread.sleep(400);
setOpening(false);
if(closing == false){
setClosed(false);
System.out.println("GATE: Opened");
}
}catch(Exception ex){
}
}
};
new Thread(task, "openThread").start();
}
}
public boolean isClosed(){
return isClosed;
}
public boolean isClosing(){
return closing;
}
public boolean isOpening(){
return opening;
}
public synchronized void setClosing(boolean t){
closing = t;
}
public synchronized void setOpening(boolean t){
opening = t;
}
public synchronized void setClosed(boolean t){
isClosed = t;
}
}
public class Controller {
public static void main(String[] args){
Track t1 = new Track("Track 1");
Track t2 = new Track("Track 2");
Gate g = new Gate();
t1.simulateTrack();
t2.simulateTrack();
do{
System.out.print("");
if((t1.isApproaching() || t1.isCrossing()) || (t2.isApproaching() || t2.isCrossing())){
if(!g.isClosed() && !g.isClosing()){
g.close();
}
}else if(g.isClosed() && !g.isOpening()){
g.open();
}
}while((t1.isSimulating() || t2.isSimulating()));
}
}
Also the code for Track
import java.security.SecureRandom;
public class Track {
private static final SecureRandom gen = new SecureRandom() ;
private boolean approaching = false;
private boolean atCrossing = false;
private boolean simulating = false;
private String trackName = "";
public Track(String n){
trackName = n;
}
public void simulateTrack(){
Runnable task = new Runnable() {
public void run() {
try {
setSimulating(true);
for(int i = 0; i < 10; i++){
Thread.sleep((gen.nextInt(5000) + 2500));
setApproaching(true);
System.out.println(trackName + ": Train is now approaching.");
Thread.sleep((gen.nextInt(5000) + 3500));
setCrossing(true);
setApproaching(false);
System.out.println(trackName + ": Train is now crossing.");
Thread.sleep((gen.nextInt(1000) + 1000));
setCrossing(false);
System.out.println(trackName + ": Train has left.");
}
setSimulating(false);
} catch (Exception ex) {
}
}
};
new Thread(task, "simulationThread").start();
}
public boolean isApproaching(){
return approaching;
}
public boolean isCrossing(){
return atCrossing;
}
public boolean isSimulating(){
return simulating;
}
public synchronized void setSimulating(boolean t){
simulating = t;
}
public synchronized void setApproaching(boolean t){
approaching = t;
}
public synchronized void setCrossing(boolean t){
atCrossing = t;
}
}
This is just an idea:
By shooting the close() logic on a background thread you lose the atomicity. The main's do loop can go around 5 times before it gives up the control of the main thread and one of the "closeThread"s start executing. Don't you see multiple "GATE: Closed"s as well?
Try this (not tested, sorry):
public synchronized void close() { // added synchornized
if (!isClosing()) { // read: "if not closing"
setClosing(true); // set closing so next time close() is called it is a no op
setOpening(false); // close other loopholes so the state is correct
System.out.println("GATE: Closing");
// we're in closing state now, because the close method is almost finished
// start the actual closing sequence
Runnable task = new Runnable() {
public void run() {
try {
Thread.sleep(400);
System.out.println("GATE: Closed");
setClosed(true);
setClosing(false);
}catch(Exception ex){
}
}
};
new Thread(task, "closeThread").start();
}
}
You'll need to modify open() the same way, so that the invariants are always kept. Checking and setting the closing and opening flags are mutually exclusive, that's what you get by placing synchronized on both of them.

Update Swing GUI from other thread

I have two classes, one of them is my thread in which I read outputs from a device through TCP/IP:
public static controlPanel cp = new controlPanel();
void startListenForTCP (final String ipaddress){
Thread TCPListenerThread;
TCPListenerThread = new Thread(new Runnable() {
#Override
public void run() {
Boolean run = true;
String serverMessage = null;
InetAddress serverAddr = null;
BufferedWriter out = null;
try
(Socket clientSocket = new Socket(ipaddress, 7420)) {
cp.updateGUI("Connection initiated... waiting for outputs!"+"\n");
char[] buffer = new char[2];
int charsRead = 0;
out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while ((charsRead = in.read(buffer)) != -1)
{
String message = new String(buffer).substring(0, charsRead);
switch (message) {
case "o,":
cp.updateGUI("Čekanje da loptica prođe RFID čitač!");
break;
case "y,":
cp.updateGUI("Hardverski problem!");
break;
case "Y,":
cp.updateGUI("Loptica nije izažla, hardverski problem!");
break;
case "I,":
cp.updateGUI("Uređaj u stanju mirovanja!!");
break;
default:
String m = message;
m = m.replaceAll("[^\\d.]", "");
try{
int i = Integer.parseInt(m);
System.out.println("Is int: "+i);
int izasao=Integer.parseInt(m);
if (redni>34){
redni=0;
}
if (izasao>0 && izasao<49){
redni =redni+1;
m=m;
ur.updateResults(redni, m);
bs.testAuto(m, redni);
System.out.println(m+ "\n");
}
} catch(NumberFormatException e){
} break;
}
}}
catch(UnknownHostException e) {
System.out.println("Unknown host..."+"\n");
} catch(IOException e) {
System.out.println("IO Error..."+"\n");
}
}
});
TCPListenerThread.start();
}
The other one is swing form in which i want to set jLabel text from the class above:
Public class controlPanel extends javax.swing.JFrame {
public static gameControler gc = new gameControler();
public controlPanel() {
initComponents();
}
public void updateGUI(final String text) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
updateGUI(text);
}
});
}jLabel5.setText(text);
System.out.println(text);
}
The message gets printed out in console but i can't set it's value to jLabel.
I need a quick way to achieve this, so any workarounds will be most helpfull.
Thank you,
Your code only updates the GUI if current thread is not the EDT:
if (!SwingUtilities.isEventDispatchThread()) {
// you call SwingUtilities.invokeLater();
}
The GUI update should also happen if the current thread happens to be the EDT. So you should change it to somehting like this:
if (SwingUtilities.isEventDispatchThread())
jLabel5.setText(text);
else
SwingUtilities.invokeLater(new Runnable() {
#Override public void run() {
jLabel5.setText(text);
}
});
Note that invokeLater() is not executed immediately but asynchronously some time later. If you need the update to happen before it returns, use SwingUtilities.invokeAndWait().
Also note that you may consider using the SwingWorker class to perform lengthy GUI-interaction tasks in a background thread.
Making it utility method
If you have to do this many times, it is profitable to make a utilitiy method for this:
public void callFromEdt(Runnable task) {
if (SwingUtilities.isEventDispatchThread())
task.run();
else
SwingUtilities.invokeLater(task); // You might want to consider
// using invokeAndWait() instead
}

Thread runOnUiThread pausing/resume after notify() not continue

Iam making app for listening .mp3 words in greek language and displaying them after 2000ms but when i pause thread and then notify() back thread never runs again... TextView is changing every 2000ms but when i pause it and notify() run() block is not executing anything anymore and app crashes.. What iam doing wrong ?
class MyinnerThread implements Runnable {
String name;
Thread tr;
boolean suspendFlag;
int i = 0;
MyinnerThread(String threadname) {
name = threadname;
tr = new Thread(this, name);
suspendFlag = false;
tr.start();
}
public void run() {
try {
while(!suspendFlag){
runOnUiThread(new Runnable() {
#Override
public void run() {
if(i == 0){tv1.setText("trhead1");}
if(i == 1){tv2.setText("trhead2");}
if(i == 2){tv3.setText("trhead3");}
if(i == 3){tv4.setText("trhead4");}
if(i == 4){tv5.setText("trhead5");}
if(i == 5){tv6.setText("trhead6");}
if(i == 6){tv7.setText("trhead7");}
if(i == 7){tv8.setText("trhead8");}
synchronized(signal) {
while(suspendFlag) {
try {
signal.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread.sleep(2000);
i++;
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
}
void mysuspend() {
suspendFlag = true;
}
void myresume() {
synchronized(signal) {
suspendFlag = false;
signal.notify();
}
}
}
EDIT: Final code here and working !
run() {
try {
while(true){
synchronized(signal) {
while(suspendFlag) {
try {
signal.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
runOnUiThread(new Runnable() {
#Override
public void run() {
//....
}
}
});
Thread.sleep(2000);
i++;
}
}
}
}
signal.wait() is called from within the UI thread (I assume, runOnUIThread will execute the given Runnable on the UI thread). This will block/freeze the UI. Take it out of the run() method and put into the threads 'main loop'.
Rethink the main loop while (!suspendFlag)! This will abort the entire task instead of just suspending it.
Finally, make suspendFlag volatile to avoid visibility issues.

how to terminate thread sendMsgToServer when exit is sent from the server side

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.atomic.AtomicBoolean;
public class ThreadSandbox {
//static volatile boolean runLoopX = true;
static AtomicBoolean runLoopX = new AtomicBoolean();
public static void main(String[] args) {
final Thread thread1 = new Thread(new Runnable(){
#Override
public void run()
{
try {
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
String userInputStr = "";
do {
System.out.println("Enter text for thread 1:");
userInputStr = userInput.readLine().trim();
System.out.println("User Input for thread 1: " + userInputStr);
} while (userInputStr.equals("e") == false && runLoopX.get()== false);
} catch (Exception e) {System.err.println(e.toString());}
runLoopX.set(true);
}
});
final Thread thread2 = new Thread(new Runnable(){
#Override
public void run()
{
try {
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
String userInputStr = "";
do {
System.out.println("Enter text for thread 2:");
userInputStr = userInput.readLine().trim();
System.out.println("User Input for thread 2: " + userInputStr);
} while (userInputStr.equals("e") == false && runLoopX.get()== false);
} catch (Exception e) {System.err.println(e.toString());}
runLoopX.set(true);
}
});
Thread thread3 = new Thread(new Runnable(){
#Override
public void run()
{
do {
if (runLoopX.get() == true) {
thread1.interrupt();
thread2.interrupt();
}
} while (runLoopX.get() == false);
}
});
thread1.start();
thread2.start();
thread3.start();
try {
thread1.join();
thread2.join();
thread3.join();
} catch (Exception e) {System.err.println(e.toString());}
}
}
Issue:
If I enter "e" for thread1 input then thread1 terminates but thread2 is still running and If I enter "e" for thread2 input then thread2 terminates but thread1 is still running.
How do I terminate both threads when "e" is entered in either threads?
you should synchronize your threads for the inputs.
but a synchronized String and made all of your threads check this string before trying to read anything
so if this string has the value "e" then the thread will terminate it self. if not just read the input but the value in the string and continue.
make sure about this String be synchronized and I would like to make it volatile
to more specific this is a bad example of threads ! if one thread will lock the application until the user enters some data. the other thread should wait in the wait queue for more performance.
in this case all of your threads will be kept in the ready queue and this will consume the CPU utilization.
to solve this problem try to use Lock and Conditions.
this is a fast pesedo-code to solve the problem on sockets :
public class ThreadSandbox {
public static syncrnized boolean continueWork = true;
public static void main(String[] args) {
final Thread thread1 = new Thread(new Runnable(){
#Override
public void run()
{ while(continueWork){
try {
socket.setSoTimeout(5 *1000);
//READ str FROM SOCKET
if(str.equals("e")) {
continueWork =false;
}
} catch (TimeoutException e) {
System.err.println(e.toString());
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
});
final Thread thread2 = new Thread(new Runnable(){
#Override
public void run()
{ while(continueWork){
try {
socket.setSoTimeout(5 *1000);
//READ str FROM SOCKET
if(str.equals("e")) {
continueWork =false;
}
} catch (TimeoutException e) {
System.err.println(e.toString());
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
});
thread1.start();
thread2.start();
}
}

Categories