How to check whether code is running in background or not? - java

In Java/Android, is there a way to check whether the currently executing line of code is executing on a background thread or not?
I have a lil' program I'm conjuring up that has finally reached the full-spaghetti stage... this was intentional, you see, because this way... if a competitor gets their hands on the code, and they "open the hood," after looking at it for more than 20 seconds, their hair will catch on fire and they'll run away screaming... but now even I am getting confused and I need to check for this condition somehow.
Exhibit-A:
// can be called from 1,067 places... some of which are background threads.
public void startDoingAFunDance(String caller, int wobbleIntensity, int spineAngle, int feetSeparationInInches) {
if (!validCallersForFunDance.contains(caller)) {
Log.i("XXX", "Caller not allowed.");
return;
}
boolean wasCalledFromBackgroundThread = // ? < what to put here > ?
Log.i("XXX", "Was startDoingAFunDance() called from a background thread? And the answer is: " + wasCalledFromBackgroundThread);
// classified
}

An easy way to know it might be the following
boolean wasCalledFromBackgroundThread = (Thread.currentThread().getId() != 1);
background threads doesn't have id 1 (UI thread has).

Related

Stop the running threads from an array

I have an array of threads and I want to start a few of them. The point is that I want to stop the threads with in a for loop.
In the for loop I want to check all threads if they are running or not, and if they are, I want to be asked if I want stop them(dialog box yes/no).
The problem is that the loop doesn't display all the times all three dialog boxes for all those three started thread. Sometime appear 1 dialog box, sometime 3 dialog boxes etc.
So, I do not have the chance to stop all three threads...
public class Main {
public static void main( String[] args )
{
Counter[] arrayOfThreads = new Counter[10];
for( int i = 0; i < arrayOfThreads.length; i++ )
{
arrayOfThreads[i] = new Counter( );
}
arrayOfThreads[3].start( );
arrayOfThreads[5].start( );
arrayOfThreads[2].start( );
for( int i = 0; i < arrayOfThreads.length; i++ )
{
if( arrayOfThreads[i].getState( ) == State.RUNNABLE )
{
int dialogButton = JOptionPane.YES_NO_OPTION;
int dialogResult = JOptionPane.showConfirmDialog( null, "Do you want to stop the theread: " + i, "Warning", dialogButton );
if( dialogResult == JOptionPane.YES_OPTION )
{
arrayOfThreads[i].stopProcessing( );
}
}
}
}
}
class Counter extends Thread
{
volatile boolean processing;
public void run( )
{
int i = 0;
processing = true;
while( processing )
{
System.out.println( " Number: " + i );
i++;
}
System.out.println( "finish" );
}
public void stopProcessing( )
{
processing = false;
}
}
EDIT:
So all what I want is when I press the EXIT button to close the threads and to dispose the frame if all the threads are stoped. I modified the first class to more more clear.
public class Program extends Frame {
public static void main(String[] args) {
Counter[] arrayOfThreads = new Counter[10];
for (int i = 0; i < arrayOfThreads.length; i++) {
arrayOfThreads[i] = new Counter();
}
Program program = new Program(arrayOfThreads);
program.startThreeThreads(1, 4, 5);
}
private Counter[] arrayOfThreads;
private JButton stopThreads;
public Program(Counter[] arrayOfThreads) {
this.arrayOfThreads = arrayOfThreads;
stopThreads = new JButton("STOP THREADS");
closeThreadsWhenExitIsPressed();
setSize(300, 200);
setLayout(new FlowLayout());
add(stopThreads);
setVisible(true);
}
public void closeThreadsWhenExitIsPressed() {
stopThreads.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
stopRunningThreadsMethod();
dispose();
}
});
}
private void startThreeThreads(int first, int second, int third) {
for (int i = 0; i < arrayOfThreads.length; i++) {
if (i == first || i == second || i == third) {
arrayOfThreads[i].start();
continue;
}
}
}
public void stopRunningThreadsMethod() {
for (int i = 0; i < arrayOfThreads.length; i++) {
if (arrayOfThreads[i].isAlive()) {
int dialogButton = JOptionPane.YES_NO_OPTION;
int dialogResult = JOptionPane.showConfirmDialog(null, "Do you want to stop the theread: " + i,
"Warning", dialogButton);
if (dialogResult == JOptionPane.YES_OPTION) {
arrayOfThreads[i].stopProcessing();
}
}
}
}
}
The documentation for getState() is (my emphasis):
Returns the state of this thread. This method is designed for use in
monitoring of the system state, not for synchronization control.
You're trying to use it for synchronization so you're already outside recommendation.
If you look at Thread.State you'll see it isn't always RUNNABLE and I suspect, as is common, System.out is synchronized so although not obvious from your code the thread could be WAITING (on another competing thread to use System.out).
Given all your thread does is hammer output it's probably quite common one or more is waiting. You could even find none show the dialog because as you go round the loop you happen to coincide with that thread waiting!
Check this by reading the state and outputting it!
So first, don't use getState() for synchronization and be aware you don't always know what synchronization is going on 'behind the scenes' in libraries you're using.
The documentation gives leave for the implementer to maybe cut corners in low-level synchronization of getState() and the value may not be 'first class' reliable (synchronized), but regardless don't do things you're told not to even if you don't know why!
The right method is isAlive(). The thread is alive if it has had its start() method called and not yet terminated. Waiting or not, it's alive...
Next problem, is because you set processing=true; in the run() method you could call stopProcessing() before processing has been set true.
There is no guarantee how far (if anywhere) down run() the thread has got when you reach stopProcessing() in the main thread.
I know there's a user interaction (e.g. big delay) but on an overloaded (or single threaded!) machine or a future use case it is possible for processing=true; to be executed after stopProcessing() sets it false. That may lead to 'runaway' processing.
So use volatile boolean processing=true; in the class declaration or set it in the constructor. That guarantees it will be set by the end of the constructor (takes place in the controlling thread) and must be before stopProcessing() is called.
Your application is (of course) a toy but think about when you would stop the threads the user didn't stop.
It's bad practice to just end the JVM without bringing all threads to a safe conclusion.
That doesn't matter in your toy but in real applications you may want to release external resources and (say) flush file buffers rather than let the JVM pull the run out.
That is, finally call stopProcessing() on all the threads in one loop and then join() in a second loop before ending the application.
It's important to use two loops because it makes sure the threads are all stopping concurrently and not one after the other.
I can't emphasise enough why you should end threads properly. People often ignore me and then long into to development have weird glitches that difficult to localise and hard to drive out.
Other considerations:
Consider using interrupt(). It's designed to help terminate threads and does nice things for you like jump them out of sleep and wait conditions (with an Interrupted exception). That will mean they may terminate faster (never slower) than your approach.
Again, not relevant in a toy but valuable in serious application.
Consider sub-classing Runnable instead of Thread. Again your toy is fine and valid but again 'real' applications end up preferring Runnable and using a thread pool of some kind (e.g. ExecutorService). That's clever because on many platforms the overhead of creating and destroying Threads is far larger than a lighter-weight Runnable.
That's the standard advice but I don't think its wisdom is always explained.
The threads probably haven't started by the time you enter the loop in main. Their states are Thread.State.NEW when you check arrayOfThreads[i].getState().
A simple solution would be either to wait some time before executing the loop to make sure the threads are running or to run a while loop over your loop to check the condition more than once.
Both are spotty and inefficient because you don't know exactly when the thread will be up and running. Instead, I would advise implementing a wait-notify mechanism to show a dialogue when the thread is certainly running.

java- How do I create a String check with a delay of a certain amount of time?

I am learning java and so far I have created a password check using if statements. However I inserted my working String check into a while loop and added Thread.sleep(3000); for a 3 second delay, however once I completed that my GUI just keeps lagging and freezing on one page as if the button was pressed. Can somebody please show me how to make a working example of a code with a String check and after a certain amount of tries a delay to stop the user from trying again?
(here is what I have:)
//var declaration
boolean match = false;
String1 = "hi";
String2 = (I know this is not code but just to omit some code:) userInput
int time = 3000;
int attempt = 0;
//check
while(!match && attempt < (maximumTries+1)){
if(String1.equals(String2)){
System.out.print("match");
}
else if(attempt < 11){
attempt++;
System.out.println("Failed:" + attempt);
}
else{
attempt++;
System.out.println("Please try again later you have:" + attempt + "failed attempts");
try{
Thread.sleep(time);
}
catch(InterruptedException ex) {
Logger.getLogger(PasswordEntry.class.getName()).log(Level.SEVERE, null, ex);
}
time = time + 1000;//1 second more every time
}
}
your code is doing an infinite loop once the first attempt does not match.
in each of the iterations of your loop there is no change at all, aside from incrementing the counter. so the counter just increases forever (with some delays in between).
it seems the reasoning behind your code was that String2 got updated with user input inside the loop not outside. This way, on each iteration you would have a different String2 to compare against.
That's your issue, not the way you delay between attempts (that for sure can be improved in any case).
You should avoid using the Thread.sleep option since it completely freezes the main thread. You could also try creating another thread, which will be frozen and later in gives a callback to the main one. For example through a boolean variable. I'd also agree on the timer solution mentioned by BladeMight.

Java TCP synchronized method

My result
Expected result
public void run () {
try {
handlers.addElement (this);
broadcast("Welcome " + name);
while(handlers.size() != 2){
if(handlers.size() > 2){
this.out.writeUTF ("The Room is full!");
this.out.flush();
handlers.removeElement(this);
socket.close();
}
}
broadcast("No of Player: " + handlers.size());
for(int i = 0; i < handlers.size(); i++){
GameHandler player = (GameHandler) handlers.get(i);
broadcast("Player " + (i + 1) + ": " + player.name);
}
System.out.println("Game starts!");
startGame(4);
....
}
protected static void broadcast (String message) {
synchronized (handlers) {
Enumeration e = handlers.elements ();
while (e.hasMoreElements ()) {
GameHandler handler = (GameHandler) e.nextElement ();
try {
handler.out.writeUTF (message);
handler.out.flush ();
} catch (IOException ex) {
handler.stop ();
}
}
}
}
The problem is the difference between the expected result and my actual result. I have no idea why the broadcast before the while loop runs normally but others run twice
Your problem is that in your case, each of the thread is sending the broadcast. Either you need to have a "master" / "server" of games thread that does the "system announcements" broadcasting, -or- elect one of the client threads (maybe the "player 1" thread?) to send the announcements.
The problem is the difference between the expected result and my actual result. I have no idea why the broadcast before the while loop runs normally but others run twice
You really don't give enough details on your problem but I see these issues:
You talk about TCP and the code mentions sockets but you are processing a local elements collection. Unless you are talking to the same JVM over TCP (which is strange) the elements collection is going to start 2 players on each client. Is that really what you expect?
Even though you says elements is a Vector you still need to synchronize on it at the start of the run() method because you are performing multiple operations on it and there are race conditions. For example, if 3 handlers are added, they will all remove themselves and close their own sockets.
Vector really is an outdated collection. You should be using something else.
When the first thread adds itself to elements it then enters a spin loop waiting for the second person to join the game. Seems like a waste there. Some small Thread.sleep(...) would be appropriate.
If the room is full I suspect that the thread should return; from the run() method. Instead it continues on which I suspect is not good.
Hope something here helps.

Concurrent puzzle solving: Java Concurrency - Cyclicbarrier. Correct usage?

I'm trying to write a program to solve 2 puzzles who can't be solved independently from eachother, but have the same solution. My idea is that they both run in a seperate thread until they stop finding new pieces of information. Then they communicate what they have found by updating some shared state variables and continue if something was written by either one of them to the shared state.
I think a CyclicBarrier is the appropriate mechanism to use here. This is my code (which is running concurrently in 2 threads:
while (true) {
doSolvingLogicHere();
shareUpdates(); // this method updates the shared state variable and is synhronized
int count;
int updates = 0;
try {
count = writeBarrier.await();
updates = threadsUpdatedSomething;
if (count == 0) {
writeBarrier.reset();
threadsUpdatedSomething = 0; //'reset' the shared value
}
} catch (InterruptedException ex) {
Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
} catch (BrokenBarrierException ex) {
Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
}
if (updates == 0) { //no thread updated something
break;
} else { // at least one of the threads updated something, solving should continue in both threads
readUpdates();
}
}
ThreadsUpdatedSomething is a shared integer which is incremented in the 'ShareUpdates()' if anything at all was updated by the threads. When both threads didn't find anything new in the iteration, this means that they never will find anything new and the whole loop should be stopped for both threads. That's why I'm checking for it to be zero.
I would expect them to both stop when both threads did not write any new information in the shared state variables. But when running the program, one of the threads stop, while the other one keeps going. When debugging the program and setting breakpoints at 'readUpdates()' line, the program works as expected.
Is this the correct way for handling such a concurrent 'solving' loop? And in case it is correct, where is the error in my code?
Thanks for the help!
EDIT: Small mistake corrected. 'updates = threadsUpdatedSomething;' now at the correct place
As per API , await returns
the arrival index of the current thread, where index getParties() - 1 indicates the first to arrive and zero indicates the last to arrive
count = writeBarrier.await();
Being said , So only one of the Thread would receive the 0 . And only one thread would set the updates value to 0. Thats why the last arrived thread stopped and other one not stopped.
As per your statements , you need to stop the threads when you find both threads not updated the threadsUpdatedSomething. i assumed that time threadsUpdatedSomething would be zero.
If not you have to change the logic , some how to find when the condition has to be break and apply it
while (true) {
doSolvingLogicHere();
shareUpdates(); // this method updates the shared state variable and is synhronized
int count;
int updates = 0;
try {
writeBarrier.await();
if (threadsUpdatedSomething == 0) {
updates = threadsUpdatedSomething;
writeBarrier.reset();
threadsUpdatedSomething -= 2; //'reset' the counter by decrementing 2
}
} catch (InterruptedException ex) {
Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
} catch (BrokenBarrierException ex) {
Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
}
if (updates == 0) { //no thread updated something
break;
} else { // at least one of the threads updated something, solving should continue in both threads
readUpdates();
}
}
Also Don't forgot to set the break conditions in exception cases if required.

How do I check how many events are happening within 2 seconds? (timer)

I need to check how many events are detected within 2 seconds. I have the timer working and I have everything else working...but I ran into a problem: the loop only checks one time, per second and I can't seem to figure out how to fix that. I need it to check constantly during these two seconds to see how many events there were in total!
Here is what I have:
int seconds = 0;
System.out.println("Seconds: " + seconds);
while(seconds < 2)
{
//Wait 1 second
try {
Thread.sleep(1000);
}
catch(Exception e) {}
seconds++;
System.out.println("Seconds: " + seconds);
//This needs to be looping the whole time.
//But right now, it's being blocked and only checked once
if(eventDetected() && seconds <= 2){
events++;
}
}
So you can see my problem. I can't split them up because then the second timer would run, and THEN eventDetected() would be checked. I need it to check constantly DURING the two second timer...so I basically need both things to happen at once. Is there any way I can do this?
Thanks for any help ahead of time!
I think your design pattern needs work -- I don't know what type event you're looking to detect, but no matter how short your sleep time is, there's a chance you could miss an event using the current pattern. Here's what I suggest:
Have eventDetected() increment your events counter. That way, you won't miss an event.
Then, you just need a way to turn on and off listening (and perhaps resetting the event counter). If you're sure that in you're current pattern you are really in a different thread that won't block your eventDetected() method, you could set a flag to check. For example:
When you want to start listening:
listenForEvents = true;
In eventDetected():
if (listenForEvents) { events++; }
When you want to stop listening (for example, after your Thread.sleep() call):
listenForEvents = false;
With multithreading, make sure to watch out for concurrency issues checking and setting the variables, of course.
I would tell you what kind of event I have to keep track of but then I'd have to kill you :D
Answered my own question. Hopefully this will help anyone else out who has a similar problem at some point! I looked up multithreading a bit...
I created a new class EventTimer which implements Runnable, with a public field for seconds:
public class EventTimer implements Runnable{
int seconds;
static int timerThreadCount = 0;
Thread t;
public EventTimer() {
timerThreadCount++;
this.seconds = 0;
t = new Thread(this, "Event Timer");
t.start(); // Start the thread
}
#Override
public void run() {
// TODO Auto-generated method stub
while(seconds < 2)
{
//Wait 1 second
try {
Thread.sleep(1000);
}
catch(Exception e) {
System.out.println("Waiting interupted.");
}
seconds++;
System.out.println("Seconds: " + seconds);
}
}
}
Then I used an instance of the EventTimer, and used a while loop & if statement to solve my problem.
EventTimer t = new EventTimer();
while(t.seconds < 2){
if(eventDetected()) events++;
}
It was actually quite simple! I realize that each iteration of my loop of operation (since the entire code piece above is inside an infinite loop) will create a new EventTimer thread and I will eventually run into memory problems however. How would I close/end a thread after the timer has reached 2 seconds?

Categories

Resources