When I run the program it does not display "HIIII."
I am a novice (sort of) so please dont "hate".
Is my wait() statement wrong? Or what am I doing wrong?
Is it the ArrayIndexOutOfBounds catch clause? Please help!
[edit] oh so is it the main method?? that it doesnt do anything?
[edit] i know the wait and notify is wrong... please don't mention it.
//this is the whole class
import javax.swing.*;
import javax.swing.JOptionPane;
public class none {
static boolean game;
final static boolean on = true;
final static boolean off = false;
static boolean cheatMode;
public static void main(String[] args) {
game = on;
boolean tru = true;
try{
if(tru = Boolean.parseBoolean(args[0])){
cheatMode = on;
System.out.println("Cheats are on.");
}
}
catch(java.lang.ArrayIndexOutOfBoundsException e){
e.printStackTrace();
System.out.println("Ignore this error, it's from not running it on the command prompt.");
}
}
public class console extends Thread{
public void run(){
try{
wait();
JOptionPane.showMessageDialog(null,"HIIII");
}
catch(Exception e){
e.printStackTrace();
System.out.println("The console glitched...");
}
//hiiii
JOptionPane.showMessageDialog(null,"HIIII");
}
public class mainThingy extends Thread{
public void run() {
if(game = on)
notify();
}
}
}
}
There seems to be couple of issues
1) if(tru = Boolean.parseBoolean(args[0])){
Above statement is assignemt and not comparison. Use == operator.
2) Wait and notify should always be called from inside Synchronized blocks. Your code doesn't seem to be doing that.
I'd advise against the standard wait()-notify() structures. There are way better methods for this: the Java concurrency package.
Tutorial for Java Concurrency
API JavaDoc
JCIP, or Java Concurrency In Practice (Peierls, Bloch, Bowbeer, Holmes, Lea)
And as you seem to be in your first steps in learning Java, I'd suggest another two books:
Effective Java (Bloch)
Java puzzlers (Bloch, Gafter)
>java none true will print only Cheats are on. But your question is about printing Hiii. Isn't it ? You have got that in JOptionPane dialog inside the console class. Without initializing it how can you expect your program to print Hiii?. Also why have you written two public classes in one file ? When you are calling wait and nottify methods, you are also missing the synchronized statement. So when you start your threads console and mainThingy those will throw IllegalMonitorStateException anyways. So actually what are you trying to do ?
You main method doesn't actually start anything
wait and notify must be synchronized on the same monitor/lock
Your two threads are not sharing the same monitor/lock
if (game = on) in mainThingy is an assignment, not a check, it should be if (game == on)
UPDATE with Example
public class TestThread {
static boolean game;
final static boolean on = true;
final static boolean off = false;
static boolean cheatMode;
public static void main(String[] args) {
game = on;
boolean tru = true;
try {
if (args.length > 0) {
if (tru = Boolean.parseBoolean(args[0])) {
cheatMode = on;
System.out.println("Cheats are on.");
}
}
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
System.out.println("Ignore this error, it's from not running it on the command prompt.");
}
Console con = new Console();
con.start();
// Give time for the console thread to get started
do {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(TestThread.class.getName()).log(Level.SEVERE, null, ex);
}
} while (!con.isAlive());
System.out.println("Start main...");
Console.MainThingy main = new Console.MainThingy();
main.start();
}
public static class Console extends Thread {
// A shared lock that our two threads can communicate on...
public static final Object WAIT_LOCK = new Object();
public void run() {
try {
System.out.println("Waiting...");
// Must "own" the monitor before we can call wait
synchronized (WAIT_LOCK) {
WAIT_LOCK.wait();
}
JOptionPane.showMessageDialog(null, "HIIII");
} catch (Exception e) {
e.printStackTrace();
System.out.println("The console glitched...");
}
}
public static class MainThingy extends Thread {
public void run() {
if (game == on) {
// Must "own" the monitor before we can call notify
synchronized (WAIT_LOCK) {
System.out.println("Notify...");
WAIT_LOCK.notify();
}
}
}
}
}
}
Java Concurrency is fun, but it will bite you if you're not careful with it and treat it nicely.
Take a read through Currency in Java
Related
Now I investigate semaphores. I googled following link about this theme:
link
Author of this link wrote about using semaphores for signaling. To show how it works he wrote custom semaphore.
custom semaphore code:
public class Semaphore {
private boolean signal = false;
public synchronized void take() {
this.signal = true;
this.notify();
}
public synchronized void release() throws InterruptedException{
while(!this.signal) wait();
this.signal = false;
}
}
about how use it in code he wrote following:
public class SendingThread {
Semaphore semaphore = null;
public SendingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run(){
while(true){
//do something, then signal
this.semaphore.take();
}
}
}
public class RecevingThread {
Semaphore semaphore = null;
public ReceivingThread(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run(){
while(true){
this.semaphore.release();
//receive signal, then do something...
}
}
}
main:
Semaphore semaphore = new Semaphore();
SendingThread sender = new SendingThread(semaphore);
ReceivingThread receiver = new ReceivingThread(semaphore);
receiver.start();
sender.start();
As I understood order of execution should be following
send - receive
send - receive
send - receive
...
I tryed to write own code using this bluerprint
public class SendReceiveWithCustomSemaphore {
public static void main(String[] args) {
MySemaphore mySemaphore = new MySemaphore();
new Send(mySemaphore).start();
new Receive(mySemaphore).start();
}
}
class MySemaphore {
boolean flag = false;
public synchronized void take() throws InterruptedException {
flag = true;
notify();
}
public synchronized void release() throws InterruptedException {
while (!flag) {
wait();
}
flag = false;
}
}
class Send extends Thread {
MySemaphore mySemaphore;
public Send(MySemaphore semaphore) {
this.mySemaphore = semaphore;
}
#Override
public void run() {
int i = 0;
while (i++ < 10) {
System.out.println("send");
try {
mySemaphore.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Receive extends Thread {
MySemaphore mySemaphore;
public Receive(MySemaphore semaphore) {
this.mySemaphore = semaphore;
}
#Override
public void run() {
while (true) {
try {
mySemaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("receive");
}
}
}
output:
send
send
send
send
send
send
send
send
send
send
receive
Thus it is not expected behaviour for me.
I made a mistake then I wrote code or I didn't understand concept ?
What did author want to say?
Find a better tutorial.
The output that you see is about what I would expect. The "sender" thread never blocks, so it will go on printing "send", "send", "send" forever. Meanwhile, over in the "receiver" thread, each time it calls the semaphore.release() method, it will be blocked until the next time the sender gets to run.
I would expect to see lots of "send" messsages, with occasional "receive" messages mixed in---more or less what you describe seeing.
I don't know what that example is supposed to prove, but for me, it creates the impression that the author does not know how programmers expect Semaphores to behave.
Some authors provide examples of what not to do, or examples containing a deliberate mistake that will be "fixed" in a later example. Are you sure you are not following an example of that kind?
Edit: I followed the link, and it looks like the main problem is that the names were swapped in the definitions of the take() and release() methods. If you just switch the names, it makes more sense.
By the time ReceiveSemafore is started SendSemafore has already executed 10 times.
Consider using a CountDownLatch to start the two threads at the same time. Although as pointed out by Fuhrmanator this will not produce the alternating output that you are looking for.
For this i would use a bounded semaphore with one signal.
import java.lang.Thread;
import java.util.Scanner;
class Running extends Thread{
private boolean Run=true;
public void shutdown(){
Run=false;
}
public void run(){
while(Run){
for(int i=0;i<1000;i++){
System.out.println("Starting Counter:"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Volatile {
public static void main(String[] args) {
Running run1=new Running();
run1.start();
System.out.println("Press any key to stop thread execution");
Scanner sc=new Scanner(System.in);
sc.nextLine();
run1.shutdown();
}
}
I am using a volatile key word to stop the thread execution. But couldn't get the solution
What should I be doing to stop the thread execution?
So your post mentions the volatile keyword but I don't see it in the code you've posted. You need to make sure that Run is a volatile boolean so that it can be changed in the main thread and the other thread will see the changes.
private volatile boolean Run=true;
But I think the problem is that you are testing for this Run only in the outer while loop. Maybe you want it also in the inner counting loop. Something like:
for(int i = 0; i < 1000 && Run; i++) {
Right now, once the loop start counting it will have to finish before the Run boolean is checked. That may be 1000 seconds in the future.
You are using the right pattern, but apply it a bit wrong:
Your Runflag will only be checked after 1000 seconds, because it will only be checked after the for loop finished. Change your code to the following:
public void run(){
while(Run){
for(int i=0;(i<1000) && (Run == true);i++){
System.out.println("Starting Counter:"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Please note you will have to completely remove the while loop if you don't want your for loop to be executed endlessly effectively.
A time ago the thread was stopped simply by calling the Thread's stop() function. Nowadays, it's deprecated because it's unsecure, so you have to stop the Thread from the inside of the Thread. You'll find a good example here. Keep in mind that doing this doesn't stop immediately the thread, it just tells it's available for stopping and Android will stop it whenever it finds it necessary.
Your code stays in the for-loop for 1000 seconds until it finally reaches the while(run) branch again. I guess this is why its not working properly.
These is the sample .You can create a boolean field and check it inside run:
public class Sample implements Runnable {
private volatile boolean isRunning = true;
public void run() {
while (isRunning) {
//do work
}
}
public void kill() {
isRunning = false;
}
}
To stop it just call
sample.kill();
This should work.
Take a look at this simple Java program:
import java.lang.*;
class A {
static boolean done;
public static void main(String args[]) {
done = false;
new Thread() {
public void run() {
try {
Thread.sleep(1000); // dummy work load
} catch (Exception e) {
done = true;
}
done = true;
}
}.start();
while (!done);
System.out.println("bye");
}
}
On one machine, it prints "bye" and exits right away, while on another machine, it doesn't print anything and sits there forever. Why?
This is because your boolean is not volatile, therefore Threads are allowed to cache copies of it and never update them. I would recommend an AtomicBoolean - that will prevent any issues you may have.
public static void main(String args[]) {
final AtomicBoolean done = new AtomicBoolean(false);
new Thread() {
public void run() {
done.set(true);
}
}.start();
while (!done.get());
System.out.println("bye");
}
By the time the main program's while loop is reached (which is also a Thread), the new Thread might be finishing its run() where done flag is set to true. Just to confirm this, you can add a sleep in the run() before done is set to true and then see if your bye is displayed on other machine also. Hope this would help.
If you look at the code I have two ArrayLists that are called, pressed and released that are global. What I have to do is update those arrays with the keys that are to be pressed, then pass these updated arrays to my Thread, or update the thread.. this is the part where I'm a little lost on what I have to do.
The currently example(untested if runs), is a basic example of what I had in my actual program. When I ran it it would press the buttons once, then it would throw and error, I can't remember the error as I can't test it right now, but it had to do with the way I was using the thread.
QUESTION
How do I pass the arrays to my Thread, once the thread has been started.
Code Example:
import oscP5.OscEventListener;
import oscP5.OscMessage;
import oscP5.OscP5;
import oscP5.OscStatus;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Main implements OscEventListener {
protected BlockingQueue<Integer> _KeyQue = new ArrayBlockingQueue<>(1024);
Producer producer = new Producer(this._KeyQue);
Consumer consumer = new Consumer(this._KeyQue);
ThreadTest threadTest = new ThreadTest(this._KeyQue);
Thread prod;
Thread con;
Thread threadT;
OscP5 osc = new OscP5(this, 22556);
public static void main(String[] argv) {
Main main = new Main();
main.setup();
}
public void setup() {
prod = new Thread(producer);
con = new Thread(consumer);
threadT = new Thread(threadTest);
prod.start();
con.start();
threadT.start();
}
#Override
public void oscEvent(OscMessage theMessage) {
float val = Float.parseFloat(theMessage.arguments()[0].toString());
if (val == 1.0) {
producer.addKey(KeyEvent.VK_W);
producer.addKey(KeyEvent.VK_S);
} else {
consumer.removeKey(KeyEvent.VK_S);
}
threadTest.run();
}
#Override
public void oscStatus(OscStatus theStatus) {}
public class Producer implements Runnable {
protected BlockingQueue<Integer> _KeyQue = null;
public void addKey(int key) {
try {
this._KeyQue.put(key);
System.out.println("Key " + key +" added to queue");
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
public Producer(BlockingQueue<Integer> _KeyQue) {
this._KeyQue = _KeyQue;
}
public void run() {
}
}
public class Consumer implements Runnable {
protected BlockingQueue<Integer> _KeyQue = null;
public void removeKey(int key) {
try {
this._KeyQue.remove(key);
System.out.println("key " + key + " removed from queue");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public Consumer(BlockingQueue<Integer> _KeyQue) {
this._KeyQue = _KeyQue;
}
public void run() {
}
}
public class ThreadTest implements Runnable {
protected BlockingQueue<Integer> _KeyQue = null;
public ThreadTest(BlockingQueue<Integer> _KeyQue) {
this._KeyQue = _KeyQue;
}
public void run() {
try {
Robot robot = new Robot();
while(!this._KeyQue.isEmpty()) {
for (Integer x : this._KeyQue) {
System.out.println("Keys in que: " + x);
Thread.sleep(500);
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
Edit:
Ok, so I've taken a look at threads and BlockingQueue's, but the thing I still can't figure out is how to continue to run the ThreadTest's run() method without locking the program. In this example it doesn't run at all. When I directly call threadTest.run() it locks the program within it and doesn't allow for adding or removing elements.
So what I need to do is be able to run a thread in the background that is constantly running, looping through *_KeysQueue()* and, in this example, printout the number associated with the keys. This should all happen while allowing me to add and remove keys.
You can have a BlockingQueue and a method to add elements that would be called from every other thread. You can have a static method addKey that could be accessed from every other thread and that would look for adding the new key to the BlockingQueue.
You can use there the producer-consumer pattern and you can see the book Java Concurrency In Practice or the link that led me to the book, in the blog The Java Specialists. The book has examples of all queues, concurrent or synchronized lists, ways to implement code to do several things, and all without having to stop to read 50 pages about something. An example and a few paragraphs of every issue.
Have a setter method in your class
public class ThreadTest implements Runnable {
....
public void setPressedList(ArrayList<Integer> e) {
this.pressed = e;
}
public void setReleasedList(ArrayList<Integer> f)
{
this.released = f
}
}
ArrayList are not thread-safe so you should not used them this way : it could work or it could fail.
Moreover you should use some kind of synchronization mechanism instead of busy-waiting which consume resources for nothing.
So have a look at the BlockingQueue collection which will give you a simple data-passing mechanism between your threads.
I am test a scenario to use volatile variable to stop one running thread from another.
I wonder why its not working. Where is the problem?
My code is:
public class StoppableTask extends Thread {
private volatile boolean pleaseStop;
public void run() {
System.out.println("Running..");
while (!pleaseStop) {
System.out.println("Working...");
}
}
public void tellMeToStop() {
pleaseStop = true;
}
}
public class Stopper extends Thread {
StoppableTask t ;
public Stopper(StoppableTask t){
this.t=t;
}
public void run(){
System.out.println("Ok..running too..");
try {
System.out.println("Waiting..");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.tellMeToStop();
System.out.println("Done Waiting..");
}
public class QuickTest{
public static void main(String[] args) {
StoppableTask t = new StoppableTask();
Stopper s = new Stopper(t);
t.start();
s.start();
}
}
I suspect that your program is printing so much output to the terminal that it is blocking waiting for the output to be displayed. It looks like it is not stopping but really it will. You just need to wait... for a long time...
You should put a Thread.sleep(100); inside of of the while() spin loop in StoppableTask.run() to slow down that output. Another way to do it is to remove the System.out and just increment a counter or something.
I just tried it and your program finishes in 5 seconds as expected:
public void run() {
System.out.println("Running..");
while (!pleaseStop) {
// System.out.println("Working...");
}
System.out.println("Stopped task Done");
}
Your program is correct.
When working with threads i suggest you to use log4j instead of system.out.println.Configure the log4j to send output to a file.
You can search your string-pattern in a file. Its easy to analyse.