I have a class "HConnection" containing multiple methods such as abort(); and awaitConnection();
The awaitConnection(); method is called in my SWT Form main class using a runnable thread. Anyways, when i abort() the HConnection, the awaitConnection isn't aborted while it should be.
Have a look at this snapshot of my main code:
private HConnection connectie;
private void btnConnect_clicked(SelectionEvent e) {
if (btnNewButton_1.getText().equals("Connect")) {
String Url = combo.getText();
connectie = new HConnection(Url);
connectie.prepare();
new Thread(new Runnable() {
public void run() {
connectie.awaitConnection();
Display.getDefault().asyncExec(new Runnable() {
public void run() {
lblNewLabel_2.setText("Waiting -> client");
if (connectie.getState() == 2) {
lblNewLabel_2.setText("Replacing URL");
}
else {
lblNewLabel_2.setText("Failed");
connectie.abort();
btnNewButton_1.setText("Connect");
}
}
});
if (connectie.getState() == 2) {
// go on
}
}
}).start();
////////
btnNewButton_1.setText("Abort");
}
else if(btnNewButton_1.getText().equals("Abort")) {
connectie.abort();
lblNewLabel_2.setText("Aborted");
btnNewButton_1.setText("Connect");
}
And a snapshot of HConnection:
public void prepare() {
addToHostsFile("127.0.0.1" + "\t" + domain);
state = 1;
}
public void abort() {
removeFromHostsFile("127.0.0.1" + "\t" + domain);
waitingConnection = false;
HostFileEdited = false;
state = 0;
}
public void awaitConnection() {
if (state == 1) {
waitingConnection = true;
System.out.println("0");
while (/* not found && */ state == 1) {
// code
}
System.out.println("1");
waitingConnection = false;
if (state == 1) state = 2;
}
}
One more note; the abort() function did actually work and finished the thread when I tried calling connectie.abort() directly after the thread.start();, (placed "////////" in the code above on that spot)
But if it's called where it should be called, it do what it should do
while
lblNewLabel_2.setText("Aborted");
btnNewButton_1.setText("Connect");
are doing their job as expected
Make your state and awaitConnection volatile :
private volatile int state;
private volatile boolean awaitConnection;
Related
Im trying to understand why this program does not work. Am i using the actionlistener properly why does it not show the time elapsed from when the thread is running but the thread is not running and i see nothing on the screen.
what am i doing wrong or this is the wrong way of using the ActionListener class
or am i not using it properly, here is the code for all the files.
import java.awt.event.*;
import java.util.TooManyListenersException;
public class Timer extends Thread {
private int iTime = 0;
private ActionListener itsListener = null;
public Timer() {
super(); // allocates a new thread object
iTime = 0; // on creation of this object set the time to zero
itsListener = null; // on creation of this object set the actionlistener
// object to null reference
}
public synchronized void resetTime() {
iTime = 0;
}
public void addActionListener(ActionListener event) throws TooManyListenersException {
if (event == null)
itsListener = event;
else
throw new TooManyListenersException();
}
public void removeActionListener(ActionListener event) {
if (itsListener == event)
itsListener = null;
}
public void run() {
while (true) {
try {
this.sleep(100);
}
catch (InterruptedException exception) {
// do nothing
}
iTime++;
if (itsListener != null) {
String timeString = new String(new Integer(iTime).toString());
ActionEvent theEvent = new ActionEvent(this,
ActionEvent.ACTION_PERFORMED, timeString);
itsListener.actionPerformed(theEvent);
}
}
}
}
next file
import java.awt.event.*;
import java.util.TooManyListenersException;
public class TextTimeDemonStration extends Object implements ActionListener {
private Timer aTimer = null; // null reference for this object
public TextTimeDemonStration() {
super();
aTimer = new Timer();
try {
aTimer.addActionListener(this);
}
catch (TooManyListenersException exception) {
// do nothing
}
aTimer.start();
}
public void actionPerformed(ActionEvent e) {
String theCommand = e.getActionCommand();
int timeElapsed = Integer.parseInt(theCommand, 10);
if (timeElapsed < 10) {
System.out.println(timeElapsed);
}
else
System.exit(0);
}
}
the last file the main class running the program from
public class MainTest {
public static void main(String[] args) {
TextTimeDemonStration test = new TextTimeDemonStration();
}
}
In TextTimeDemonStration class, you called aTimer.addActionListener(this); to assign an action listener
But in your Timer.addActionListener() method, in the if else block, you wrote
if (event == null)
itsListener = event;
else
throw new TooManyListenersException();
Since this is not null, it will throw TooManyListenersException exception which will be caught.
After which you start the timer. But, since itsListener is null after the initialisation, in your Timer.run() method, the if block will never be executed. Therefore, nothing is done.
Fix up the logic at Timer.addActionListener() method and it should work just fine.
Hope this helps.
I am trying to plot data received from Bluetooth with real-time with MPAndroidChart library. I believe there is problem with thread deadlocks but I cannot figure it out exactly.
Here is how the code goes:
After connection is established, when "Read" button is pressed.
public boolean onOptionsItemSelected(MenuItem item) {
Intent serverIntent;
if (dtToggle.onOptionsItemSelected(item)) { return true; }
switch (item.getItemId())
{ ......
case R.id.menu_read:
String message;
if (oper_state) {
oper_state = false;
put_thread = new PutTask();
put_thread.start();
timer = new Timer();
timer.schedule(new MyTask(),10, 100);
//feedMultiple();
//put_thread.start();
message = CMD_READ + "";
sendMessage(message);
} else {
if(timer != null)
{
message = CMD_STOP + "";
sendMessage(message);
put_thread.interrupt();
timer.cancel();
timer.purge();
timer = null;
oper_state = true;
//put_thread.interrupt();
try{
if(fos != null)
fos.close();
}
catch(Exception e)
{
}
}
}
return true;
PutThread is where I add received data from bluetooth to data queue:
class PutTask extends Thread {
public void run(){
int channel_idx;
customParsePackets mBluetoothService;
while(true)
{
mBluetoothService = mChestPatchService;
for(int i=0;i<num_siganl_list;i++)
{
if(!mBluetoothService.isEmpty(i))
{
int read_data = mBluetoothService.poll_data(i);
put_data(i, read_data);
sample_incr(i);
}
}
}
}
}
Put_data function:
public synchronized void put_data(int i, int int_data)
{
int tmp_sample = 0;
int tmp_data, filtered_data;
double tmp_diff_val=0;
tmp_sample = sample_get_value(i);
tmp_data = int_data;
if(mECGSignCheck.isChecked())
tmp_data = -tmp_data;
if(mFilterCheck.isChecked() == true)
ecg_data[i] = ECG_bpf[i].getOutputSample(tmp_data);
else
ecg_data[i] = tmp_data;
if(i==1) {
tmp_diff_val = mRpeak.put_ecg(tmp_sample, tmp_data);
peak_point = mRpeak.Apply_ecg();
Log.d("PEAK", "Data pushed" );
}
synchronized (chartQueue_Lock){
if(tmp_sample % 4 == 0)
**chartQueue[i].offer(new Point(tmp_sample, (int)ecg_data[i]));**
}
}
And this is where I update my UI:
class MyTask extends TimerTask {
public void run(){
runOnUiThread(new Runnable(){
#Override
public void run(){
//updateui();
dataseries_add_new((int)(Math.random() * 7),0, Math.random() * 500);
}
});
}
}
The above code works perfectly fine for GraphView Library. But I want to implement it for MPAndroidChart.
For MPAndroidChart when I start do dataseries_add_new((int)(Math.random() * 7),0, Math.random() * 500); in the above class it works well. But my goal is to add the data from the data queue to the graphs. So in order to do so, in the above code sample instead of dataseries_add_new((int)(Math.random() * 7),0, Math.random() * 500); I call updateui() from where I poll the data from the queue and call dataseries_add_new((int)(Math.random() * 7),0, Math.random() * 500);:
public void updateui()
{
long starttime, endtime;
int tmp_sample = sample_get_value(APW_SIGNAL);
Point qPoint = new Point();
for(int i=0; i<num_siganl_list; i++)
{
int poll_num = 0;
while(!chartQueue[i].isEmpty())
{
if(poll_num != 0)
{
if(qPoint.x % 4 == 0) {
dataseries_add_new(i, qPoint.x, qPoint.y);
}
}
synchronized (chartQueue_Lock)
{
qPoint = chartQueue[i].poll();
}
poll_num = 1;
}
Where the graph update code is taken from MPAndroidChart sample app for Realtime Chart.
When "Read" button is presed app screen goes black for some time and then gives an error. Could you please provide some insight about how to solve the problem?
how can I rebuild my method:
public class PDFCheck {
public static void testAllFontsAreEmbedded(PDFDocument pdf) throws PDFDocumentException {
for (PDFFont font : pdf.listFonts()) {
if (!font.isEmbedded()) {
errorMessageBuffer.append("font not embedded: " + font.getName() + "\n");
fontError = "font error";
}
}
into a Thread like that here:?
public class Task1 implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
................
................
................
................
}
}
}
In main I will do like this:
Thread t1 = new Thread(new Task1());
t1.start();
t1.interrupt();
I want to do that because I've developed a pdf check tool and a stop button should stop the "font chek" (see above code snippet) when a pdf is too large and takes too long to be checked.
I tried this to build a constructor, but the constructor shows a lot of error messages:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
public static void testAllFontsAreEmbedded(PDFDocument pdf) throws PDFDocumentException {
for (PDFFont font : pdf.listFonts()) {
if (!font.isEmbedded()) {
fontError = "font error" + " | ";
} else {
fontError = "";
}
}
System.out.println("läuft");
}
}
}
UPDATE: I integrate finally a Thread in this method. The Proble now is that the method just choose all the time the first pdf file of the path...Is my while statement at a wrong position?
new Thread() {
#Override
public void run() {
String directory;
directory = "C:\\Users\\Tommy\\Desktop\\pdf";
File inputFiles = new File(directory);
CopyOfSettingsGui.this.running = true;
for (File file : inputFiles.listFiles()) {
if (file.isFile()) {
if (file.getName().endsWith((".pdf"))) {
while (CopyOfSettingsGui.this.running) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.print(file.getName() + "\n");
}
return;
}
}
}
}
}.start();
You can pass the pdf as described in the answer of Conffusion, but if you want to use interrupt() you have to make your thread 'interuptable' This method don't stops the thread unless your thread is invoking methods that throw 'Interrupted Exception' or checks the 'interrupted flag'. So you have to invoke ´Thread.interrupted()´ in every iteration.
public void run() {
for (PDFFont font : pdf.listFonts()) {
if (Thread.interrupted()){
return;
}
...
}
}
Alternatively, you can set a member variable to stop the thread:
class PDFCheckThread extends Thread {
private boolean stop;
public PDFCheckThread(PDFDocument pdf) {
this.pdf = pdf;
}
public void setStopFlag() {
stop = true;
}
public void run() {
for (PDFFont font : pdf.listFonts()) {
if(stop) {
return;
}
...
}
}
}
You have to pass the PDF to the Task1 constructor and store it in a local variable (within Task1. From within the run() method you can access the PDF document:
public class Task1 implements Runnable {
private PDFDocument pdf;
public Task1 (PDFDocument pdf) {
this.pdf=pdf;
}
public void run() {
for (PDFFont font : pdf.listFonts()) {
if (!font.isEmbedded()) {
fontError = "font error" + " | ";
} else {
fontError = "";
}
}
System.out.println("läuft");
}
}
}
To launch the thread:
Thread t1 = new Thread(new Task1(myPDFInstance));
t1.start();
t1.interrupt();
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.
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.