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.
Related
The goal is to have String of output's consisting of W's, X's ,y's
and z's.
W and X should alternate and W must always be ahead of X.
y and z must alternate with y always ahead of z.
The total of y's and z's must be less than the number of W's at any given point in the output.
My program so far satisfies the first two points but I'm having trouble with the last one. Also, I very new to semaphore's and want to know if the code I've implemented follows good practices. For example, I had originally set the initial value of my binary semaphores to 0,1,2,3 but changed it to 0,1,0,1 in order to satisfy the second condition.
public class BinarySemaphore extends Semaphore{
public BinarySemaphore(int initial) {
value = (initial>0) ? 1 : 0;
}
public synchronized void P() throws InterruptedException {
while (value==0) {
wait();
}
value = 0;
}
public synchronized void V() {
value = 1;
notify();
}
}
public class ProcessW extends App implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(1 + (int) (Math.random() * 500));
bsX.P();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.print("W");
bsW.V();
}
}
}
public class ProcessX extends App implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(1 + (int) (Math.random() * 500));
bsW.P();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.print("X");
bsX.V();
}
}
}
public class ProcessY extends App implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(1 + (int) (Math.random() * 800));
bsZ.P();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.print("y");
bsY.V();
}
}
}
public class ProcessZ extends App implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(1 + (int) (Math.random() * 800));
bsY.P();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.print("z");
bsZ.V();
}
}
}
public class App {
protected static final BinarySemaphore bsW = new BinarySemaphore(
0);
protected static final BinarySemaphore bsX = new BinarySemaphore(
1);
protected static final BinarySemaphore bsY = new BinarySemaphore(
0);
protected static final BinarySemaphore bsZ = new BinarySemaphore(
1);
public static void main(String[] args) throws Exception {
Thread W = new Thread(new ProcessW());
Thread X = new Thread(new ProcessX());
Thread Y = new Thread(new ProcessY());
Thread Z = new Thread(new ProcessZ());
W.start();
X.start();
Y.start();
Z.start();
Thread.sleep(3000);
System.out.println("");
System.exit(0);
}
}
Here is an example of what my program is currently outputting:
WXWyzXWXWXyzyWXWXzyzWXyzWXyzWX
Your goal is not defined very well because you didn't write what means are you required to use to achieve the goal. For instance, a program that always prints "WXyzWX" satisfies your question. But I'll assume you specifically want to use four threads each printing its own letter, and you want to use Semaphores for this.
Semaphores are used to manage a number of "permissions" between different threads. A thread can semaphore.acquire() a permission and semaphore.release() it after doing its job. If no permissions are available at the moment of calling acquire(), the thread waits until some other thread releases a permission. See documentation for details.
You can use Semaphores for your purpose, but before that I have to explain what "fairness" means in terms of multithreading. By default, the Semaphore (and all other Java concurrent stuff) is "unfair". This means that when a permission is released, it will be given to any of the threads that are waiting for one, considering the overall performance first. On the other hand, a "fair" Semaphore will always give a newly available permission to the thread that has been waiting for one for the longest time. This practically orders the threads as if in a queue. In general, fair structures work slower, but in our case this fairness is very useful.
Now to the idea. You can think of your letter ordering in a following way: to write X, a thread needs a permission that will only be available to it after another thread writes W, and then to write W you will need a permission from X thread. So you can use a semaphore for these two threads, with each thread acquiring and releasing a permission from the semaphore before and after printing the letter. And its fairness guarantees that W and X will always be alternating (don't forget that by default semaphores are unfair, you have to specify a flag in its constructor in order to make it fair). You should also make sure which thread acquires the permission first, or else you will get X always ahead of W.
You can make a similar trick to alternate y and z, but now you have to guarantee your third condition. This is also doable using a semaphore: to write a y or a z, you need a permission that can only be acquired after some W-s were written. I'm going to make you think this one through by yourself. Maybe a nice idea would be to randomly decide whether to release a permission or not, but no details here :)
I must mention that this is by far not the only way to accomplish your task, and also semaphores may be not the best tool to use in here. (I don't think a specific best one exists though.)
And now some extra comments on your code:
What exactly is your purpose of extending the java Semaphore? You never use any of its methods. You can just delete that 'extends' if you want to use this code.
To generate a random value from 0 to N, there is a nextInt(N) method in java.util.Random class. It suits your purposes better.
InterruptedException is one of the few ones that can be safely ignored most of the times (unless you know what it means and want to use it). I mention it because in case it is thrown, your output is going to be mixed up with letters and exceptions.
You simply create a thread, start it and then never access it. In this case, you can simplify your lines to new Thread(new ProcessW()).start() without even creating a variable.
P() and V() are terrible names for methods - I can barely understand what they are supposed to do.
What is the purpose of your BinarySemaphore fields in App class being protected? Did you mean private?
You're stopping all of your threads by calling System.exit(0). This way you cannot make a difference which threads to stop and which not to, as well as being unable to do anything after stopping the threads. A simple solution would be to create a volatile boolean isRunning = true; visible to all threads (do you know what volatile is?), replace while(true) to while(isRunning) and instead of calling System.exit() just do isRunning = false. Or else use the interruption mechanism (again, if you know what it is).
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.
I'm writing a program in Java that will allow a person to input data into a form as jobs for a help desk. The submitted form is then used to create a helpRequest object which is entered into a generic Queue for storage in a binary file. However, the onus of the project (it's a school assignment) is to make the program failsoft using exceptions. One specific stipulation of the program is that it must handle any situation where it cannot continue by attempting to save the current helpRequest queue before terminating "gracefully". I've got all of this set up in code, but when the handler runs (by a division by zero in my test), the program hangs as soon as it tries to do anything with the helpQueue.
I've tried looking up Java global variables and global exception handlers, but nothing seems to address the topic of using a structure or variable from another/the throwing class.
Here is the code for the handler. I have helpQueue declared as public and static in the throwing class HelpDeskForm, and NetBeans accepts all the code I have here. The induced exception occurs after the queue has been worked with.
public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler {
BinaryOutputFile emergencyOutput;
public void uncaughtException(Thread t, Throwable e) {
Frame f = new Frame();
JOptionPane.showMessageDialog(f, "Program error. Please select a file for queue output.");
emergencyOutput = new BinaryOutputFile();
while(!HelpDeskForm.helpQueue.isEmpty())
emergencyOutput.writeObject(HelpDeskForm.helpQueue.remove());
emergencyOutput.close();
System.exit(1);
}
}
Rather than a specific solution to my issue, I'd appreciate it if someone could explain why helpQueue is seemingly not actually visible/usable in this exception handler, or what I'm doing horribly wrong.
EDIT: I didn't want to overcomplicate my explanation, but here is the HelpDeskForm code up until my division by zero exception.
public class HelpDeskForm {
BinaryDataFile input;
BinaryOutputFile output;
CheckedForm c;
helpRequest r;
public static Queue<helpRequest> helpQueue;
int inputSize;
public HelpDeskForm() {
GlobalExceptionHandler h = new GlobalExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(h);
input = new BinaryDataFile();
inputSize = input.readInt();
for(int i = 0; i < inputSize; i++) {
helpQueue.add((helpRequest)input.readObject());
}
input.close();
int y = 0;
int z = 2;
z = z/y;
... // GUI code follows
}
}
HelpDeskForm seems to lack initialization for queue being used, so NPE is inevitable. Try to add initialization to declaration:
public static Queue<helpRequest> helpQueue = new ArrayBlockingQueue<helpRequest>(100);
Plus, for the posted code, it would be logical to add volatile keyword to queue declaration:
public static volatile BlockingQueue<helpRequest> helpQueue;
public void createQueue() {
// make sure createQueue() is called at the very beginning of your app,
// somewhere in main()
helpQueue = new ArrayBlockingQueue...
}
This way all other threads, if any, will see correct reference to the queue, and thread safety of BlockingQueue guarantees correct visibility of its' contents.
I changed the code to a much more detailed version so you can get a better idea of my problem.
I need to "watch" an integer value and immediately respond to when it changes. So far the best way I've found is using a thread in an infinite loop.
The following is a vastly simplified portion of my project. To summarize, notificationValue is set to 1 by a click of a button within my Bubble class. I need the applet to be able to monitor this notificationValue and respond whenever it changes.
Here is my applet:
public class MyApplet extends JApplet
{
Bubble myBubble = new Bubble();
public void run()
{
new Thread(
new Runnable() {
public void run() {
while(true) {
if(myBubble.getNotificationValue() == 1) {
/* here I would respond to when the
notification is of type 1 */
myBubble.resetNotificationValue;
}
else if(myBubble.getNotificationValue() == 2) {
/* here I would respond to when the
notification is of type 2 */
myBubble.resetNotificationValue;
}
else if(myBubble.getNotificationValue() != 2) {
/* if it is any other number other
than 0 */
myBubble.resetNotificationValue;
}
// don't do anything if it is 0
}
}
}).start();
}
}
And here is my class:
public class Bubble extends JPanel
{
public JButton bubbleButton;
public int notificationValue = 0;
public int getNotificationValue()
{
return notificationValue;
}
public void resetNotificationValue()
{
notificationValue = 0;
}
protected void bubbleButtonClicked(int buttonIndex)
{
notificationValue = buttonIndex;
}
public Bubble()
{
bubbleButton = new JButton();
bubbleButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event)
{
bubbleButtonClicked(1);
}
});
}
}
But obviously that keeps the CPU up at 100% and isn't efficient at all. What would be a better way to do this? (Assume I can't change any of the methods responsible for changing the integer.)
immediately respond to when it changes
How "immediate" does that need to be exactly? Adding a Thread.sleep(10) in your while loop would probably bring down your CPU load to near zero.
What would be a better way to do this? (Assume I can't change any of the methods responsible for changing the integer.)
A better way would be not to expose fields directly. A great example for the benefits of encapsulation - having a setter method would make it trivial to implement the observer pattern.
If that int happens to be a property of a JavaBean, you could use a PropertyChangeListener.
However, I suspect that if you need to monitor some integer for a value change you've got a design problem. It'd be better to make sure that integer can only be changed through some method and make sure that method handles the required logic based on the old and new values.
You could use wait/notify. You could use an ExecutorService. A lot depend on whether you can change the code where the integer is set.
Try adding a Thread.sleep(1); to save CPU.
You can check value of your variable time to time to save CPU. Or use pattern Observer
Could you encapsulate the integer in another class, wrap with a setter and getter and add a notification (via an Observer)?
Assuming you can't change the code which actually sets the integer there isn't much you can do. That being said, if you call Thread.yield() at the end of each pass the impact the thread has on the performance of other applications will be minimal.
I have trouble with continuous image loading&processing&display in Swing:
Below there is simple case where clicking a button causes my program to grab frame from webcam and then display this picture in jlabel. It works as it should, but i have to consecutively click this "Start" button in order to get new image(frame) shown.
private void StartActionPerformed(java.awt.event.ActionEvent evt) {
displayed_img = this.getPIC_COLOR(player);
img_field.setIcon(new ImageIcon(displayed_img));
}
Im more demanding and i would like to make some image processing during live video stream, therefore i need to "grab" & "show" my frames continuously. You might say that i can just launch webcam stream, but it is not what i want to achieve since i'm about to implement some threshholding/etc. functions which will modify my image on-fly. Therefore i need to perform this grabbing&processin&display as fast as possible (delay is a no-no since i want to achieve something like 10 fps including image processing). Despite the fact that i delay is utterly undesirable i tried to make some Thread.sleep however it didnt work.
Simple while(true) /* presented below */ does not work, my program "hangs" and not even single frame is displayed, although in debugger it keeps working over and over.
private void StartActionPerformed(java.awt.event.ActionEvent evt) {
while(true){
displayed_img = this.getPIC_COLOR(player);
//threshholding & further processing...
img_field.setIcon(new ImageIcon(displayed_img));
}
}
just in case getPIC_COLOR() was required, i paste it below:
public BufferedImage getPIC_COLOR(Player player){
FrameGrabbingControl frameGrabber = (FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl");
Buffer buf = frameGrabber.grabFrame();
Image img = (new BufferToImage((VideoFormat)buf.getFormat()).createImage(buf));
BufferedImage buffImg = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffImg.createGraphics();
g.drawImage(img, null, null);
return buffImg;
}
Any help greatly appreciated.
Ok, after some reading i managed to write some SwingWorker Code:
private void SingleFrameActionPerformed(java.awt.event.ActionEvent evt) {
SwingWorker<Void, BufferedImage> worker = new SwingWorker<Void, BufferedImage>() {
#Override
protected Void doInBackground() {
while (!isCancelled()) {
displayed_img = getPIC_COLOR(player);
publish(displayed_img);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
return null;
}
#Override
protected void process(List mystuff) {
Iterator it = mystuff.iterator();
while (it.hasNext()) {
img_field.setIcon(new ImageIcon(displayed_img));
try {
ImageIO.write(displayed_img, "png", new File("c:\\testimg.jpg"));
} catch (IOException ex) {
Logger.getLogger(TestCAMGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
#Override
protected void done() {
infoBAR.setText("FINISHED");
}
};
worker.execute();
}
Now what seriously bothers me is the fact that my img_field is not updated in swing, although ImageIO.write present in process works, and image is "redrawn" on C:\ with MAD speed ("mad speed" is highly desirable). Moreover my GUI is still frozen even though i created this swing worker thread...
btw i also tried to "sleep" this saving thread for a second, however my GUI hangs even with this additional sleep
Now some explanations about my code:
doInBackground() returns void, as i dont need to return anything, since i assume this process will run till cancelled (which is unlikely to happen, unless program is closed).
inside process() i've included try/catch block with ImageIO.write just to make sure my thread launched and works
i didnt use 'SwingUtilities.invokeLater' due to fact that browsing guides/tutorials i've read that it is better to use SwingWorker in my case
What bothers me furthermore: in process i operate on list which enlarges... i dont need that, i just need a single element and thats all. So is there a way to collect single object from doInBackground()? making list seems memory waste for me. Or maybe i should clear() the list at the end of process()? (in order to reduce memory allocated)
Any further hints are appreciated.
You must not run any kind of infinite loop of that form in a method that is called from an event (unless you explicitly intend to hang your user interface, which would be odd to say the least).
You should run your frame grab in a separate thread, and then use something like SwingUtilities.invokeLater to display it.