I'm trying to write a java applet program that creates a thread and does two things:
Print numbers in the normal flow of execution
repaint the applet in thread
please take a look at the following code
public class Sample extends applet implements Runnable
{
Thread t=new Thread(this);
int y=500;
public void init()
{
t.start();
for(int i=0;i<30;i++)
{
System.out.print(i);
try {
Thread.sleep(1000);
} catch(Exception e) {}
}
}
public void run()
{
while(true)
{
repaint()
if(y==100) y=500; else y-=100;
}
}
public void paint(Graphics g)
{
g.fillOval(50,y,50,50);
}
}
I wrote this code thinking that a black ball will move up and down and at the same time prints numbers but when i run it it prints numbers and the ball doesn't move until it prints all the numbers. I can't understand why.
You do your printing from the .init() method. Like I said in comments, above, I don't know much about AWT/Swing, and I know even less about the Applet class, but maybe you should do your printing from .start() instead.
The Javadoc says that .init() is called to "inform the applet that it has been loaded," and start() is called "to inform the applet that it should start running."
Like I also said in the comments, above. I would use a timer to drive the animation, and not explicitly create a thread.
I probably would use a timer to drive the counting too: I'd write a .start() method that just starts the two timers and returns.
Related
I've run into a problem in which java is interpreting my code completely wrong and I don't know how to change that. Since my program is too complicated to really explain I'm going to give a generalized description of my problem and hope you are able to give me a generalized answer.
In my code there is something along the lines of this:
function1();
object.function2();
function1();
function1 alters the object.
When I run this I get an exception while it's inside function2 (meaning the code never gets to the third line). However when I remove the third line, the code runs without any problems. This means that the java compiler is compiling my code in such a way that the second call of function1 has some influence on the previous line in which object.function2 is called.
What is also interesting is that if you insert a breakpoint between line 2 and 3, it always works while debugging.
Is this normal? Is there any principle in java that is causing this, and any way to stop this?
The code is available at this Bitbucket Repository, but be warned, it is undocumented spaghetti code and probably goes against every convention in java code. The problem described is inside Pool.java starting with line 41.
I hope the little information I've given here is sufficient for some kind of explanation.
Alright, I think to have figured this out enough, to be able to create an answer that might help you (for sure) and hopefully other people.
There is indeed multithreading involved, because
object.function2();
is creating a JFrame f. All drawing operations inside that frame f are executed by an AWT-EventQueue-0 (or any other number) task T. This task T is run parallel to your main thread M. Meaning every datastructure l (like a list) that is drawn in a custom JPanel p inside f and altered by M will potentially cause problems.
Example
public static void main(String[] args) {
List<Integer> l = new ArrayList<Integer>(5);
JFrame gui = new JFrame();
gui.add(new MyPanel());
l.add(10);
}
public class GUI extends JPanel {
private List<Integer> l;
public MyPanel(List<Integer> l) {
this.l = l;
}
#Override
public void paintComponent(Graphics g) { // this is called by JFrame.paint()
super.paintComponent(g);
List<Integer> modifiedL = new ArrayList<Integer>(l.size());
for(Integer i : l) {
modifiedL.add(2 * i);
}
// this is a stupid example, because it makes no sense to
// use this loop with l.size() here, but it shows the main problem.
for(int c = 0; c < l.size(); c++) {
somehowDrawSthWith(modifiedL.get(c));
}
}
}
By now changing the size of l after making the call to create the JFrame we cause an ArrayOutOfBoundsException when trying to access modifiedL.get(5), because the modifiedList may be created before l.add(10).
(A possible) Solution
Note that I wrote possible, because this is hacky and just be avoided if possible.
We need the Main thread M to wait until everything is painted. Here is a way to do this:
Java wait for JFrame to finish
In our example we would can change the main to:
public static void main(String[] args) {
List<Integer> l = new ArrayList<Integer>(5);
CountDownLatch jFrameDrawing = new CountDownLatch(1);
JFrame gui = new JFrame();
gui.add(new MyPanel(), jFrameDrawing); // add the counter
try {
jFrameDrawing.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
l.add(10);
}
And count down at the end of the drawing method like this
#Override
public void paintComponent(Graphics g) { // this is called by JFrame.paint()
super.paintComponent(g);
// ...
jFrameDrawing.countDown();
}
Now note, that this method might be called multiple times before p is really fully drawn. The reason is the following
Is the paint function in java graphics called multiple times when I add a JComponent?
So if your main looks like this:
public static void main(String[] args) {
List<Integer> l = new ArrayList<Integer>(5);
CountDownLatch jFrameDrawing = new CountDownLatch(3); // NOTE 3
JFrame gui = new JFrame();
gui.add(new MyPanel(), jFrameDrawing); // draw once
gui.setSize(100,50); // draw again
gui.setVisible(true); // draw a third time
try {
jFrameDrawing.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
l.add(10);
}
You need to set the initial counter to 3.
TL;DR:
Using AWT classes (e.g. JFrame) in
object.function2();
will create multithreading. This might create race conditions, like lists being modified concurrently.
See Java wait for JFrame to finish on how to think the drawing with the main code.
I am currently working on understanding the Java concept of multithreading. I went through a tutorial which uses the Tortoise and the Hare example to explain the concept of multithreading, and to a large extent I understood the syntax and the logic of the video tutorial. At the end of the video tutorial, the Youtuber gave an assignment that involves applying Multithreading to an olympic race track.
Using my knowledege from the example, I was able to create 10 threads (representing the athletes) that run within a loop, that executes 100 times (representing 100 meters).
My challenge is that when the Thread scheduler makes an Athlete to get to 100 meters before the other 9 athletes, the remaining 9 threads always do not complete their race. This is not usually the case in a standard race track. The fact that a Thread called Usain Bolts gets to 100 first, does not mean Yohan Blake should stop running if he is at 90m at that time.
I am also interested in getting the distance (note that they are all using the same variable) for each thread, so that I can use a function to return the positions of each Thread at the end of the race.
What I have done (that did not work):
1) I have tried to use an if else construct (containing nine "else"
statement) to assign the distance of each executing thread to a new integer variable. (using the Thread.currentThread().getName() property and the name of each thread) but that did not work well for me. This was an attempt to give positions to the athletes alone using their distance but does nothing about the 9 athletes not finishing the race.
2) I have also tried to use an ArrayList to populate the distance at runtime but for some strange reasons this still overwrites the distance each time it wants to add another distance.
Below are my codes:
package olympics100meters;
import java.util.ArrayList;
public class HundredMetersTrackRules implements Runnable {
public static String winner;
public void race() {
for (int distance=1;distance<=50;distance++) {
System.out.println("Distance covered by "+Thread.currentThread ().getName ()+" is "+distance+" meters.");
boolean isRaceWon=this.isRaceWon(distance);
if (isRaceWon) {
ArrayList<Integer> numbers = new ArrayList();
numbers.add(distance);
System.out.println("testing..."+numbers);
break;
}
}
}
private boolean isRaceWon(int totalDistanceCovered) {
boolean isRaceWon=false;
if ((HundredMetersTrackRules.winner==null)&& (totalDistanceCovered==50)) {
String winnerName=Thread.currentThread().getName();
HundredMetersTrackRules.winner=winnerName;
System.out.println("The winner is "+HundredMetersTrackRules.winner);
isRaceWon=true;
}
else if (HundredMetersTrackRules.winner==null) {
isRaceWon=false;
}
else if (HundredMetersTrackRules.winner!=null) {
isRaceWon=true;
}
return isRaceWon;
}
public void run() {
this.race();
}
}
This is my main method (I reduced it to 5 Athletes till I sort out the issues):
public class Olympics100Meters {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
HundredMetersTrackRules racer=new HundredMetersTrackRules();
Thread UsainBoltThread=new Thread(racer,"UsainBolt");
Thread TysonGayThread=new Thread (racer,"TysonGay");
Thread AsafaPowellThread=new Thread(racer,"AsafaPowell");
Thread YohanBlakeThread=new Thread (racer,"YohanBlake");
Thread JustinGatlinThread=new Thread (racer,"JustinGatlin");
UsainBoltThread.start();
TysonGayThread.start();
AsafaPowellThread.start();
YohanBlakeThread.start();
JustinGatlinThread.start();
}
}
My challenge is that ... the remaining 9 threads always do not complete their race.
This is caused by isRaceWon() method implementation. You check for it at each meter at each runner. As soon as the first runner achieves 100 meters, the break is called on next step of each runner loop (the race is won for every loop
btw, it makes sense to use volatile statuc String for winner's name, to avoid java's memory model ambiguities.
I am also interested in getting the distance ... for each thread, so that I can use a function to return the positions of each Thread at the end of the race.
If the final aim is to get the position, create a class field public List<String> finishingOrder = new ArrayList<String> and a method finish
private synchronized finish() {
finishingOrder.add(Thread.currentThread().getName())
}
and call it after the "run" loop
do not forget to call join() for all runner threads in your main. After that, the finishingOrder will contain names in order of finishing.
The code snippet below is causing isRaceWon to return true for every instance of HundredMetersTrackRules as soon as the shared winner field is set to non-null (i.e. someone wins.):
else if (HundredMetersTrackRules.winner!=null) {
isRaceWon=true;
}
This in turn causes the loop in race() to break for every instance of your Runnable. The run() method exits, terminating the thread.
The issue is just a logic error and not really specific to threading. But, as other posters have mentioned, there's some threading best-practices you can also adopt in this code, such as using volatile for fields shared by threads.
Actually For Race you need to start all the Threads at once then only its Race.
CountDownLatch is better one to Implement or write Race Program.
Many other way also we can write Race program without using the CountDownLatch.
If we need to implement using base / low level then we can use volatile boolean Flag and counter variable in synchronized blocks or using wait() and notifyAll() logic, etc.,
Introduced some time delay in your program inside the for loop. Then only you can feel the Experience. Why because you are not starting all the threads at once.
Hope you are Practicing Initial / base Level so I made few changes only for better understanding and Addressed all your queries.
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
class HundredMetersTrackRules implements Runnable {
public static Main main;
HundredMetersTrackRules(Main main){
this.main=main;
}
public static String winner;
public void race() {
try{
System.out.println(Thread.currentThread().getName()+" Waiting for others...");
while(!Main.start){
Thread.sleep(3);
}
for (int distance=1;distance<=50;distance++) {
System.out.println("Distance covered by "+Thread.currentThread().getName()+" is "+distance+" meters.");
Thread.sleep(1000);
}
synchronized(main){
Main.finish--;
}
Main.places.add(Thread.currentThread().getName());
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
public void run() {
this.race();
}
}
public class Main
{
public static volatile boolean start = false;
public static int finish = 5;
final static List<String> places =
Collections.synchronizedList(new ArrayList<String>());
public static void main(String[] args) {
HundredMetersTrackRules racer=new HundredMetersTrackRules(new Main());
Thread UsainBoltThread=new Thread(racer,"UsainBolt");
Thread TysonGayThread=new Thread (racer,"TysonGay");
Thread AsafaPowellThread=new Thread(racer,"AsafaPowell");
Thread YohanBlakeThread=new Thread (racer,"YohanBlake");
Thread JustinGatlinThread=new Thread (racer,"JustinGatlin");
UsainBoltThread.start();
TysonGayThread.start();
AsafaPowellThread.start();
YohanBlakeThread.start();
JustinGatlinThread.start();
Main.start=true;
while(Main.finish!=0){
try{
Thread.sleep(100);
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
System.out.println("The winner is "+places.get(0));
System.out.println("All Places :"+places);
}
}
This is a piece of code in a SCJP practice question:
public class Threads2 implements Runnable {
public void run() {
System.out.println("run.");
throw new RuntimeException("Problem");
}
public static void main(String[] args) {
Thread t = new Thread(new Threads2());
t.start();
System.out.println("End of method.");
}
}
It was partly mentioned here.
However, my question is not the prior question. As I run the program on a few machines multiple times, I occasionally get RuntimeException before "run" in the output. This does not make sense to me, as these lines of codes executed in the same thread, so it should have been the reverse order.
Can anyone explain why that happens?
e.printStacktrace is using System.err.
System.out and System.err are different object. It has Buffered writer to display to client window.
Even it will execute in different order , it will go to different Buffer.
If Err buffer prints first err will come first.Otherwise out will come first.
I make two threads: one for fill an array and the second one print it. It seems like the two thread don't work in same time.
When i run the code its print first thread working then its print the array and second thread working how i can know if they working on same time or not?
here is my code:
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
firstthread f=new firstthread();
secondthread s=new secondthread();
s.start();
f.start();
}
}
and the class the contain both fill and print method:
public class Array {
private static int [] ar=new int[500];
public static void fillarray()
{
for (int i = 0; i < ar.length; i++)
ar[i]=i;
}
public static void printarray()
{
for (int i = 0; i < ar.length; i++)
System.out.print(ar[i]+" ");
}
}
the first thread class:
public class firstthread extends Thread{
public void run() {
Array.fillarray();
System.out.print("first thread working ");
}
}
the second thread class:
public class secondthread extends Thread{
public void run() {
Array.printarray();
System.out.println("second array working");
}
}
The fillarray and printarray methods are running too fast so you aren't getting threading.
Add Thread.sleep(10) to each loop. That way the code will run much slower and the threads will intersperse. They will probably alternate with this approach.
Then change in to sleep a random # of seconds and you'll see different behavior.
You want an implementation of producer-consumer problem bro... Frankly speaking, without having a lock on the Object's monitor, you dont have control over anything. You dont have control over how much time a thread executes (Timeslice provided to it). If the time slice is too long, you will feel that one thread executes after another because your processor is so fast, your first thread will get ample time to finish its work . If you want to know how threads work exactly, use wait() and notify() and synchronized methods to change it into a producer-consumer problem.
Jeanne is also right, you can put sleep() , there's a 90 percent chance that it might work.
You could increase the number of elements being filled/printed.
There's a 70% chance of you reading more than what you wrote(filled in the array) if you dont use syncronized/wait/notify.
Starting a thread takes some time to the JVM. The first thread executes its run() method faster than the other thread is started. That's why you see that behavior.
Question isn't clear. Do you mean how can you tell if they are working on the same array? If that is the case the answer is Yes. the array is static meaning there would be only one of its kind which would belong to the class array. So there wont be multiple instances of it being worked on by the different threads.
As stated above, the threads run very fast. So even though they are accessing the same object, one thread would finish its job before the second even begins
I'm currently working on a small game that consisted of a few targets that pop up at random for various amounts of time. The actual game will get it's I/O from a circuit board since the targets are physical.
My problem is that currently I have a java.util.Timer that fire's off every 2 seconds. Once it is triggered a random target will be displayed (which works fine so far). The problem is that I want to display the targets for a random number of seconds between 1-5 whilst the timer is still running and setting off other targets.
I get no errors and the targets display but never disappear. I guess it's some sort of Thread issue and that maybe since I'm using this.* the Target objects are just somehow getting lost in the nether! After searching around the questions here I have come up with this:
public class Target implements Runnable(){
...
public void displayFor(int seconds){
this.display();
Executors.newSingleThreadScheduledExecutor().schedule(this,time,
TimeUnit.SECONDS);
this.setDisplayed(false);
}
#Override
public void run() {
this.destroy();
}
}
Basically the initial game timer (that sets of the Targets display) calls the displayFor(2) method which runs the targets run method after the time passed. The Targets still won't disappear though.
I have tried a number of different ways of doing this like the displayFor() setting off another java.util.Timer and I also had a go at using the Quartz library (which to be honest seemed like overkill anyway) and still can't get it to work. Since there are no error messages I'm really stuck with this one.
I've haven't included a lot of the code because I don't think it's that relevant but if you guys need more information to help just let me know :)
I managed to get it working. Here's the correct code for anyone in a similar situation.
public class Target{
private Timer timer;
...
public void displayFor(int seconds) {
// send the output
BoardInterface.SetDigitalChannel(this.getId());
// calculate the delay
long time = seconds * 1000;
// create a new timer and schedule the new task
timer = new Timer();
timer.schedule(new TargetTimer(this), time);
this.setDisplayed(true);
}
}
class TargetTimer extends TimerTask{
Target target;
public TargetTimer(Target t){
this.target = t;
}
#Override
public void run() {
target.destroy();
}
}
Not sure if this is a good way of doing it but it works. If you notice anything that could be improved please let me know. Thanks guys!
Perhaps you should tell us what the display method does.
Are you un-displaying the target in the destroy/destructor code?
I'd recommend, instead of void display():
public void setDisplayed(boolean display){
if(display) {
///... do appropriate circuit output to turn on target
} else {
/// ... do appropriate circuit output to turn off target
}
}
and of course
public void run(){
setDisplayed(false);
destroy();
}