I have the following nested class inside a class that implements MouseListener:
public void plusOne()
{
int reference = 0;
int status = 0;
System.out.println("BEGIN");
System.out.println(dateArray[reference].selected);
while (dateArray[reference].selected = false)
{
reference++;
System.out.println("SUCCESS");
}
while (dateArray[reference].selected = true)
{
reference++;
}
while (true)
{
if (dateArray[reference].status == 2)
{
dateArray[reference].status =1;
status =2;
break;
}
if (dateArray[reference].status == 3)
{
dateArray[reference].status =0;
status = 3;
break;
}
dateArray[reference].selected = true;
reference++;
dateArray[reference].status = status;
}
}
System.out.prinln("BEGIN") is executed.
System.out.prinln(dateArray[reference].selected) is also executed. It should display the value "false" but it ALSO displays an error message of type
"Exception in thread "AWT-EventQueue-0" false
The next while loop is not executed.
Help Please!
you wrote wrong syntax in java, trace your code and try like example code below
while (dateArray[reference].selected == false){
while (dateArray[reference].selected == true){
Your main problem is that you're trying to force linear command line program type code into a single threaded event-driven programming environment, and this will likely completely freeze your GUI. For example this:
public void plusOne() {
int reference = 0;
int status = 0;
System.out.println("BEGIN");
System.out.println(dateArray[reference].selected);
while (!dateArray[reference].selected) {
reference++;
System.out.println("SUCCESS");
}
// ... here
Is fine in a simple console program since program code flow is dictated solely by you the programmer, but note that you'd likely have code within the while loop for user to enter code, and the program would wait patiently for the user to do this, then the loop would check the condition and decide whether to re-ask the user for input or proceed beyond the loop.
But this won't work in a single threaded Swing program since that while loop will block the Swing event dispatch thread and would then completely freeze the GUI. The solution is to get rid of the while loop and instead use if blocks and instance fields and vary your method's response depending on the state of the fields. The details of how you would implement this would depend on the details of your program and code, something we don't really know yet, but that you should tell and show us.
The = should be ==
public void plusOne()
{
int reference = 0;
int status = 0;
System.out.println("BEGIN");
System.out.println(dateArray[reference].selected);
while (!dateArray[reference].selected) //-----------
{
reference++;
System.out.println("SUCCESS");
}
while (dateArray[reference].selected) //-------------
{
reference++;
}
while (true)
{
if (dateArray[reference].status == 2)
{
dateArray[reference].status =1;
status =2;
break;
}
if (dateArray[reference].status == 3)
{
dateArray[reference].status =0;
status = 3;
break;
}
dateArray[reference].selected = true;
reference++;
dateArray[reference].status = status;
}
}
Related
I have two threads doing calculation on a common variable "n", one thread increase "n" each time, another decrease "n" each time, when I am not using volatile keyword on this variable, something I cannot understand happens, sb there please help explain, the snippet is like follow:
public class TwoThreads {
private static int n = 0;
private static int called = 0;
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
n = 0;
called = 0;
TwoThreads two = new TwoThreads();
Inc inc = two.new Inc();
Dec dec = two.new Dec();
Thread t = new Thread(inc);
t.start();
t = new Thread(dec);
t.start();
while (called != 2) {
//System.out.println("----");
}
System.out.println(n);
}
}
private synchronized void inc() {
n++;
called++;
}
private synchronized void dec() {
n--;
called++;
}
class Inc implements Runnable {
#Override
public void run() {
inc();
}
}
class Dec implements Runnable {
#Override
public void run() {
dec();
}
}
}
1) What I am expecting is "n=0,called=2" after execution, but chances are the main thread can be blocked in the while loop;
2) But when I uncomment this line, the program when as expected:
//System.out.println("----");
3) I know I should use "volatile" on "called", but I cannot explain why the above happens;
4) "called" is "read and load" in working memory of specific thread, but why it's not "store and write" back into main thread after "long" while loop, if it's not, why a simple "print" line can make such a difference
You have synchronized writing of data (in inc and dec), but not reading of data (in main). BOTH should be synchronized to get predictable effects. Otherwise, chances are that main never "sees" the changes done by inc and dec.
You don't know where exactly called++ will be executed, your main thread will continue to born new threads which will make mutual exclusion, I mean only one thread can make called++ in each time because methods are synchronized, and you don't know each exactly thread will be it. May be two times will performed n++ or n--, you don't know this, may be ten times will performed n++ while main thread reach your condition.
and try to read about data race
while (called != 2) {
//System.out.println("----");
}
//.. place for data race, n can be changed
System.out.println(n);
You need to synchronize access to called here:
while (called != 2) {
//System.out.println("----");
}
I sugest to add getCalled method
private synchronized int getCalled() {
return called;
}
and replace called != 2 with getCalled() != 2
If you interested in why this problem occure you can read about visibility in context of java memory model.
I created a utility class for getting info about the running threads. one thread called MQTT_THREAD starts when a button is pressed. and i have another button named play, when pressed it should check first if the thread MQTT_THREAD exists or not or ,in other words, was born or not.
At run time, i press the button that starts the MQTT_THREAD, and when I press the play button, it displas that the thread MQTT_THREAD is not existing. I believe its mostl because my ack of understaning threads or a small bug in the logic. Below is my code.
Kindly please have a lok at it and let me know what i am missin.
Code_utitlity methods used
public static Thread[] getAllRunninthreads() {
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
return threadArray;
}
public static boolean isThreadExist(String threadName) {
boolean isExist = false;
for (int i = 0; i < ThreadsUtility.getAllRunninthreads().length; i++) {
if (ThreadsUtility.getAllRunninthreads()[i].getName().equals(threadName)) {
return (isExist = true);
}
}
return isExist;
}
Code_at the main thread:
if (e.getSource() == Bplay) {
if (!ThreadsUtility.isThreadExist(MQTT_THREAD)) {
System.out.println(MQTT_THREAD + " is not existing.");
}else {
System.out.println(MQTT_THREAD + " exists.");
if (!ThreadsUtility.isThreadExist(FILE_THREAD)) {
System.out.println(FILE_THREAD + " is not existing.");
}else {
System.out.println(FILE_THREAD + " exists.");
}
}
Try calling getAllRunninThreads just once as calling it again and again would not give you consistent value of set/array (imagine creating new thread or exiting a thread) and hence would create issue.
public static boolean isThreadExist(String threadName) {
Thread[] threads = ThreadsUtility.getAllRunninthreads();
for (int i = 0; i < threads.length; i++) {
if (threads[i].getName().equals(threadName)) {
return true;
}
}
return false;
}
This is what api has to say for getAllStackTraces method
A zero-length array will be returned in the map value if the virtual machine has no stack trace information about a thread.
The Thread.getAllStackTraces().keySet(); displays all the available threads n the stack, but not the TERMINATED ones. So, i think your "mqtt thread" might not making heavy work that consumes time, therefore, by the time you press the "play" buton the thread might have finished its work and hence, TERMINATED and would not be listed in the Thread.getAllStackTraces().keySet()
Let's say I have the following class:
public class BuggyClass {
private String failField = null;
public void create() {
destroy();
synchronized (this) {
failField = new String("Ou! la la!");
}
}
public void destroy() {
synchronized (this) {
failField = null;
}
}
public long somethingElse() {
if (failField == null) {
return -1;
}
return failField.length();
}
}
It's easy to see that in a multithreaded execution of the above code we could get a NullPointerExeption in somethingElse. For example, it could be that failField != null and before returning failField.length() destroy gets called therefore making failField to null.
I want to create a multithreaded program that is going to be able to "throw" a NullPointerException when using BuggyClass. I know, that since the program is multithreaded, it could be that this never happens but I guess there should be some better test that increases the probability of getting an exception. Right?
I tried the following:
final BuggyClass bc = new BuggyClass();
final int NUM_OF_INV = 10000000;
int NUM_OF_THREADS = 5;
ExecutorService executor = Executors.newFixedThreadPool(3 * NUM_OF_THREADS);
for (int i = 0; i < (NUM_OF_THREADS); ++i) {
executor.submit(new Runnable() {
public void run() {
for(int i = 0; i< NUM_OF_INV; i++){
bc.create();
}
}
});
}
for (int i = 0; i < (NUM_OF_THREADS); ++i) {
executor.submit(new Runnable() {
public void run() {
for(int i = 0; i< NUM_OF_INV; i++){
bc.destroy();
}}
});
}
for (int i = 0; i < (NUM_OF_THREADS); ++i) {
executor.submit(new Runnable() {
public void run() {
for(int i = 0; i< NUM_OF_INV; i++){
bc.somethingElse();
}}
});
}
executor.shutdown(); executor.awaitTermination(1, TimeUnit.DAYS);
I executed the above code (method) multiple times with different NUM_OF_INV and NUM_OF_THREADS but NEVER managed to get a NullPointerException.
Any ideas on how I can create a test that increases my chances of getting an exception without changing BuggyClass?
Although there is a data race in your code, it might be impossible to see any problems, that are caused by this data race. Most likely, the JIT compiler will transform the method somethingElse into something like this:
public long somethingElse() {
String reg = failField; // load failField into a CPU register
if (reg == null) {
return -1;
}
return reg.length();
}
That means, the compiler will not load the reference failField after the condition. And it is impossible to trigger the NullPointerException.
Update: I have compiled the method somethingElse with GCJ to see some real and optimized assembler output. It looks as follows:
long long BuggyClass::somethingElse():
movq 8(%rdi), %rdi
testq %rdi, %rdi
je .L14
subq $8, %rsp
call int java::lang::String::length()
cltq
addq $8, %rsp
ret
.L14:
movq $-1, %rax
ret
You can see from this code, that the reference failField is loaded once. Of course, there is no guarantee, that all implementations will use the same optimization now and forever. So, you shouldn't rely on it.
It does fail... on my machine at least. The thing is that the Runnable swallows the exception. Try instead:
executor.submit(new Runnable() {
public void run() {
for (int i = 0; i < NUM_OF_INV; i++) {
try {
bc.somethingElse();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
});
I get NPE's every time I run it.
If you just want to see the problem, you could add short sleeps before you call failField.length() and also immediately after the failField = null in the destroy() method. This would widen the window for the somethingElse() method to access the variable in a null state.
I'm surprised that nobody has noticed the fact that "failedField" was not prefixed with a volatile keyword.
While it's true there is an opportunity for a race to occur in the create() method, the reason why it probably works on other people's machines is the fact that "failedField" was not in shared memory and a cached value of "failedField" was used instead.
Also, references on 64 bit machines aren't as threadsafe as you think. That's why AtomicReference exists in java.util.concurrent
I want the JTextFiled to go up quickly as if it were a clock
the following code is inside a mouse listener.
Also t1 IS public and was declared before the main method in the class.
If you any questions pleas tell me!
ddd = 1. The rest of the switch statement is the same just instead of t1 its t2 or t3 or t4...
try {
String rol = null;
String har = null;
int rolx = 0;
int harx = 0;
int newl = 0;
switch (ddd) {
case 1:
rol = t1.getText();
har = numb.getText();
rolx = Integer.parseInt(rol);
harx = Integer.parseInt(har);
newl = rolx + harx;
while (harx > 0) {
harx --;
rolx ++;
Thread.sleep(10);
System.out.println(""+rolx);
t1.setText(""+rolx);
}
t1.setText(""+newl);
break;
Anything you do directly inside a Listener's event handling code holds the event handling thread, preventing any GUI activity.
You need to either move the loop to another thread, or use some form of timer instead.
I'm trying to create a simple queue with Java Thread that would allow a loop, say a for loop with 10 iterations, to iterate n (< 10) threads at a time and wait until those threads are finished before continuing to iterate.
Here's a better way to illustrate my problem:
for (int i = 1; i <= 10; i++) {
new Thread ( do_some_work() );
if ( no_available_threads ) {
wait_until_available_threads();
}
}
do_some_work() {
// do something that takes a long time
}
Basically what I want to do is a copy of this: Thread and Queue
How can I achieve this the most painless way?
I would use the Java 5 Executors instead of rolling your own. Something like the following:
ExecutorService service = Executors.newFixedThreadPool(10);
// now submit our jobs
service.submit(new Runnable() {
public void run() {
do_some_work();
}
});
// you can submit any number of jobs and the 10 threads will work on them
// in order
...
// when no more to submit, call shutdown, submitted jobs will continue to run
service.shutdown();
// now wait for the jobs to finish
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
Use the Executors, as recommended by the others. However, if you want the fun of doing it yourself, try something like this. (Take care. I wrote it in Notepad and there's some Exceptions you'll need to catch even if I got everything else right. Notepad's poor at catching coding errors.) This is more a concept than an actual solution to anything, but the idea could be generally useful.
private ConcurrentLinkedQueue<MyThread> tQueue =
new ConcurrentLinkedQueue<MyThread>();
class MyThread extends Thread {
public Runnable doSomething;
public void run() {
// Do the real work.
doSomething();
// Clean up and make MyThread available again.
tQueue.add( mythread );
// Might be able to avoid this synch with clever code.
// (Don't synch if you know no one's waiting.)
// (But do that later. Much later.)
synchronized (tQueue) {
// Tell them the queue is no longer empty.
tQueue.notifyAll();
}
}
}
Elsewhere:
// Put ten MyThreads in tQueue.
for (int i = 0; i < 10; i++) tQueue.add( new MyThread() );
// Main Loop. Runs ten threads endlessly.
for (;;) {
MyThread t = tQueue.poll();
if (t == null) {
// Queue empty. Sleep till someone tells us it's not.
do {
// There's a try-catch combo missing here.
synchonized( tQueue ) { tQueue.wait() };
t = tQueue.poll();
} while (t == null) break; // Watch for fake alert!
}
t.doSomething = do_some_work;
t.start();
}
Also, note the clever use of ConcurrentLinkedQueue. You could use something else like ArrayList or LinkedList, but you'd need to synchronize them.
see java.util.concurrent and especially Executors and ExecutorService
Crate Logger.class :
public class Logger extends Thread {
List<String> queue = new ArrayList<String>();
private final int MAX_QUEUE_SIZE = 20;
private final int MAX_THREAD_COUNT = 10;
#Override
public void start() {
super.start();
Runnable task = new Runnable() {
#Override
public void run() {
while (true) {
String message = pullMessage();
Log.d(Thread.currentThread().getName(), message);
// Do another processing
}
}
};
// Create a Group of Threads for processing
for (int i = 0; i < MAX_THREAD_COUNT; i++) {
new Thread(task).start();
}
}
// Pulls a message from the queue
// Only returns when a new message is retrieves
// from the queue.
private synchronized String pullMessage() {
while (queue.isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
}
}
return queue.remove(0);
}
// Push a new message to the tail of the queue if
// the queue has available positions
public synchronized void pushMessage(String logMsg) {
if (queue.size() < MAX_QUEUE_SIZE) {
queue.add(logMsg);
notifyAll();
}
}
}
Then insert bellow code in your main class :
Logger logger =new Logger();
logger.start();
for ( int i=0; i< 10 ; i++) {
logger.pushMessage(" DATE : "+"Log Message #"+i);
}