Results 1 to 20 of 25
- 07-01-2011, 11:06 PM #1
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
need help in locking or synchronization
Dear All,
I have a code fragment that is not working. I posted it before on this same forum, but now the problem is better defined, and the code is changed a bit.
I am having event dispatch thread trouble again, the thing is that when i run the program by clicking the 1-step button, it executes perfectly, but when i press start, then half the total no of grids do no get repainted. The other half does, I'm at my wits end at how to solve this problem.
I have pasted the code below, I know it's long, but could someone please take a look at it?
There is a save file that you need to load, to make it run. I would be more than happy to provide it and the remaining code if required.
The problem lies in the part somewhere between when I call the update function and the repaint function in the first code. The problem of half the array not showing gets sorted out if i use the synchronized keyword to equate the arrays, but then the results aren't correct, as the arrays tend to get equated the moment i put a new value in buffer[][]. I think I need to somehow lock the program so that it doesn't execute further till the update function is complete. The code is correct, but not robust, as it executes much better in a friend's laptop.
I will much appreciate any help. Thanks.
Problematic Code fragment:
Paint Component code:Java Code:while( true ){ if( running ){ startTime = System.currentTimeMillis(); exchanges.update(); elapsedTime = System.currentTimeMillis() - startTime; waitTime = Math.max( delayTime - elapsedTime, 5 ); try{ Thread.sleep(waitTime); }catch (InterruptedException ie) {} da.repaint(); }
Update Code:Java Code:public void paintComponent( Graphics g ){ // main rendering recipe Graphics2D g2 = (Graphics2D)g; g2.setColor( Color.black ); g2.fillRect( 0, 0, getWidth()-1, getHeight()-1 ); int w = DISP_WIDTH / exchanges.width; int h = DISP_HEIGHT /exchanges.height; for(int col=0;col<exchanges.width;col++){ for(int row=0;row<exchanges.height;row++){ for(int k=0; k<11; k++){ //replaced with works1.l if( exchanges.cells[col][row] == k ){ if( exchanges.buffer[col][row] == exchanges.cells[col][row] ) g2.setColor( exchanges.colarray[k] ); // is and was a cooperator } } g2.fillRect( col * w +1, row * h +1, w-2, h-2 ); } } }
Java Code:public void update(){ int maxValue = set[0][0]; for(int i=1;i < set.length;i++){ if(set[i][0] > maxValue){ maxValue = set[i][0]; } } int minValue = set[0][0]; for(int i=1;i<set.length;i++){ if(set[i][0] < minValue){ minValue = set[i][0]; } } for(int col=0; col<width; col++) { for( int row=0; row<height; row++) { int count = 0; if( ( (col-13+set[0][1]) >= 0 ) && ((row-10+minValue) >= 0) && ( (col-13+set[set.length-1][1]) < width) && (row-10+maxValue)<height ) { for( int r=0; r<rules.length; r++) { if (cells[col][row] == child [r][0][0]) { for( int i=0; i<set.length; i++) { if( rules[r][set[i][1]][set[i][0]] == cells [col-13+set[i][1]][row-10+set[i][0]] ) { count++; } } if(count == set.length) {buffer[col][row] = child[r][1][0];} count = 0; } } } } } for (int i=0; i<width; i++) { for(int j=0; j<height; j++) { cells [i][j] = buffer [i][j]; // new = old } } }
-
I hope that I'm wrong, but I'm not sure that we have enough information to be able to solve your problem. For instance, how are we to guess what any of this means?:
when i run the program by clicking the 1-step button, it executes perfectly, but when i press start, then half the total no of grids do no get repainted.Last edited by Fubarable; 07-02-2011 at 12:21 AM.
- 07-02-2011, 12:33 AM #3
Is the repainting of the grids controlled by logic in the paintComponent method?half the total no of grids do no get repainted
I can't see the nesting of the logic because of the misaligned {}s.
- 07-02-2011, 01:19 AM #4
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
Dear Fubarable,
In 1-step, I basically call update() and repaint() individually, and then they work fine. but when i call them in the while loop shown below:
because of the multiple threads running, they lose their robustness, and the paint component function doesn't work properly. Half the grid executes perfectly, the other half doesn't. For example, I am scanning the grid column-wise, then the first 10-15 columns will stay blank, the remainder will get repainted.Java Code:while( true ){ if( running ){ startTime = System.currentTimeMillis(); exchanges.update(); elapsedTime = System.currentTimeMillis() - startTime; waitTime = Math.max( delayTime - elapsedTime, 5 ); try{ Thread.sleep(waitTime); }catch (InterruptedException ie) {} da.repaint(); }
It is varying from pc to pc, as I said.
If you need the entire code, I can provide it for understanding the issue better, but i'm not sure if I can upload the particular save file that needs to be loaded to make it run on the forum.Last edited by samanyu; 07-02-2011 at 01:30 AM.
- 07-02-2011, 01:23 AM #5
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
Dear Norm, I hope this is better.
Java Code:public void paintComponent( Graphics g ) { Graphics2D g2 = (Graphics2D)g; g2.setColor( Color.black ); g2.fillRect( 0, 0, getWidth()-1, getHeight()-1 ); int w = DISP_WIDTH / exchanges.width; int h = DISP_HEIGHT /exchanges.height; for(int col=0;col<exchanges.width;col++) { \\start of first nested for for(int row=0;row<exchanges.height;row++) { \\start of second nested for for(int k=0; k<11; k++) { \\start of third nested for if( exchanges.cells[col][row] == k ) { \\start of if condtn. if( exchanges.buffer[col][row] == exchanges.cells[col][row] ) g2.setColor( exchanges.colarray[k] ); } \\end of if condtn. } \\end of third nested for g2.fillRect( col * w +1, row * h +1, w-2, h-2 ); } \\end of second nested for } \\end of first nested for } \\ end of methodLast edited by samanyu; 07-02-2011 at 01:27 AM.
- 07-02-2011, 02:45 AM #6
I don't see how to help without a complete program that compiles and executes. Try making a small program that compiles and executes and demonstrates the problem. What is the save file you need to run this with?
- 07-02-2011, 02:52 AM #7
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
The program needs a set of rules to work, its a cellular automata program, the file contains the arrays that contain the neighborhood and rules.
It is a simple file, non-executable. I will make a small program if you like, but it'll be a little difficult. I can remove the useless code from the original program and somehow upload the save file somewhere and post a link.
Will that help?
- 07-02-2011, 02:55 AM #8
Yes, I think it would.
- 07-02-2011, 03:53 AM #9
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
This is a light-weight version of the program.
Class Iteration1:
Class Iteration2:Java Code:import javax.swing.*; // the Java eXtensions "Swing" graphics kit import java.awt.*; // the Java Abstract Windowing Toolkit import java.awt.image.*; // the AWT image package import java.awt.geom.*; // AWT geometry import java.awt.event.*; // AWT Event Management package import java.io.*; // I/O package // Iterated brahma with some simplified controls and cell editing capabilities public class Iteration1 extends JFrame implements ActionListener { public static final int DISP_WIDTH = 1024; // constants public static final int DISP_HEIGHT = 768; private static final int MNU_HEIGHT = 22; public static int CELL_PXL = 16; private static final int FPS = 5; public Container con = null; public DisplayArea da = null; public Iteration2 exchanges = null; public boolean running = false; public static void main (String args[]) throws IOException { new Iteration1(); } public Iteration1(){ // con5structor set up thread loops super("Brahma-II"); JFrame frame = new JFrame("Brahma-II"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setResizable(true); con = getContentPane(); con.setLayout(null); setupMenus(); exchanges = new Iteration2( DISP_WIDTH/CELL_PXL, DISP_HEIGHT/CELL_PXL ); da = new DisplayArea( new Rectangle( 0, 0, DISP_WIDTH, DISP_HEIGHT ) ); con.add( da ); con.addMouseListener( da ); setVisible(true); resizeToInternalSize5( DISP_WIDTH, DISP_HEIGHT + MNU_HEIGHT); long delayTime = 1000/FPS; // main loop long startTime, waitTime, elapsedTime; while( true ){ if( running ){ startTime = System.currentTimeMillis(); exchanges.update(); elapsedTime = System.currentTimeMillis() - startTime; waitTime = Math.max( delayTime - elapsedTime, 5 ); try{ Thread.sleep(waitTime); }catch (InterruptedException ie) {} da.repaint(); } } } public void resizeToInternalSize5( int internalWidth, int internalHeight ){ Insets insets = getInsets(); final int newWidth = internalWidth + insets.left + insets.right; final int newHeight = internalHeight + insets.top + insets.bottom; Runnable resize = new Runnable(){ // an anonymous inner class public void run(){ setSize( newWidth, newHeight); } }; if(!SwingUtilities.isEventDispatchThread() ){ try{ SwingUtilities.invokeAndWait( resize ); }catch( Exception e ) { } } else{ resize.run(); } validate(); } public JMenuBar menuBar; public JMenu fileMenu; public JMenuItem clearItem; public JMenu gridMenu; public JMenuItem openRulItem; public JButton startButton; public JButton stopButton; public JButton stepButton; public void setupMenus(){ menuBar = new JMenuBar(); this.setJMenuBar(menuBar ); fileMenu = new JMenu("File"); menuBar.add( fileMenu ); clearItem = new JMenuItem("Clear Grid"); clearItem.addActionListener( this ); fileMenu.add(clearItem); fileMenu = new JMenu("Grid"); menuBar.add( fileMenu ); openRulItem = new JMenuItem("Load Rules"); openRulItem.addActionListener( this ); fileMenu.add(openRulItem); fileMenu.add( new JSeparator() ); startButton = new JButton("Start"); startButton.addActionListener( this ); menuBar.add(startButton); stopButton = new JButton("Stop"); stopButton.addActionListener( this ); menuBar.add(stopButton); stepButton = new JButton("1-Step"); stepButton.addActionListener( this ); menuBar.add(stepButton); menuBar.validate(); } public void actionPerformed( ActionEvent ev ){ if( ev.getSource() == openRulItem ){ // handle reloading from file JFileChooser chooser = new JFileChooser( new File( System.getProperty("user.dir", "." ) ) ); // JFileChooser chooser = new JFileChooser(); int returnVal = chooser.showOpenDialog(this); if(returnVal == JFileChooser.APPROVE_OPTION) { File inputFile = chooser.getSelectedFile(); try{ FileInputStream fis = new FileInputStream( inputFile ); ObjectInputStream ois = new ObjectInputStream( fis ); exchanges.set=(int[][])ois.readObject(); exchanges.rules = (int[][][])ois.readObject(); exchanges.child = (int[][][])ois.readObject(); fis.close(); }catch( Exception e ){ System.out.println("Error Opening file: " + inputFile.getName() ); e.printStackTrace(); } } } else if ( ev.getSource() == clearItem) { exchanges.blank(0); da.repaint(); }// process the con5trol events else if( ev.getSource() == startButton ){ // start running running = true; } else if( ev.getSource() == stopButton ){ // stop background thread running = false; } else if( ev.getSource() == stepButton ){ // do exactly ONE step exchanges.update(); da.repaint(); } } public class DisplayArea extends JPanel implements MouseListener{ public DisplayArea( Rectangle bounds ){ // default con5structor setLayout(null); setBounds( bounds); setOpaque(false); setPreferredSize( new Dimension (bounds.width, bounds.height ) ); } public void paintComponent( Graphics g ){ // main rendering recipe Graphics2D g2 = (Graphics2D)g; g2.setColor( Color.black ); g2.fillRect( 0, 0, getWidth()-1, getHeight()-1 ); int w = DISP_WIDTH / exchanges.width; int h = DISP_HEIGHT /exchanges.height; for(int col=0;col<exchanges.width;col++){ for(int row=0;row<exchanges.height;row++){ for(int k=0; k<11; k++){ //replaced with works1.l if( exchanges.cells[col][row] == k ){ if( exchanges.buffer[col][row] == exchanges.cells[col][row] ) g2.setColor( exchanges.colarray[k] ); // is and was a cooperator } } g2.fillRect( col * w +1, row * h +1, w-2, h-2 ); } } } public void mousePressed( MouseEvent mev ){} public void mouseReleased( MouseEvent mev ){} public void mouseEntered( MouseEvent mev ){} public void mouseExited( MouseEvent mev ){} public void mouseClicked( MouseEvent mev ){ int i = mev.getX() / CELL_PXL; int j = mev.getY() / CELL_PXL; if( i < exchanges.width && j < exchanges.height ){ for (int k=0; k<11; k++){ if( exchanges.cells[i][j] == k ){ // toggle the value exchanges.cells[i][j] = k+1; exchanges.buffer[i][j] = k+1; break; }} if (exchanges.cells[i][j] == (11)){ exchanges.cells[i][j] = 0; exchanges.buffer[i][j] = 0; // toggles the old behaviour too for clarity } da.repaint(); } } } }
This is what the GUI looks like. I have uploaded the save file at wolfram3 - 4shared.com - online file sharing and storage - download.Java Code:import java.io.*; import java.awt.*; public class Iteration2 { // Iterated Prisoner's Dilemma on x,y grid public static int cells[][]; // our 2D array of prisoner cells1 public static int buffer[][]; // use this for an intermediate update buffer1 public static int tmp[][]; // use as a reference (uninstantiated) to do the swapover int width; // number of player cells1 horizontally int height; // number of player cells1 vertically public boolean sweeping = false; public int set[][]; public int rules[][][]; public int child[][][];// controls the update algorithm used Color[] colarray = {Color.blue, Color.green, Color.yellow, Color.red, Color.orange, Color.cyan, Color.magenta, Color.pink, Color.lightGray, Color.darkGray, Color.white}; public void blank(int val){ // clear all the cells1 to val (either DEFECTOR or COOPERATOR) for(int col=0;col<width;col++){ for(int row=0;row<height;row++){ cells[col][row] = val; buffer[col][row] = cells[col][row]; } } } public void update(){ int maxValue = set[0][0]; for(int i=1;i < set.length;i++){ if(set[i][0] > maxValue){ maxValue = set[i][0]; } } int minValue = set[0][0]; for(int i=1;i<set.length;i++){ if(set[i][0] < minValue){ minValue = set[i][0]; } } for(int col=0; col<width; col++) { for( int row=0; row<height; row++) { int count = 0; if( ( (col-13+set[0][1]) >= 0 ) && ((row-10+minValue) >= 0) && ( (col-13+set[set.length-1][1]) < width) && (row-10+maxValue)<height ) { for( int r=0; r<rules.length; r++) { if (cells[col][row] == child [r][0][0]) { for( int i=0; i<set.length; i++) { if( rules[r][set[i][1]][set[i][0]] == cells [col-13+set[i][1]][row-10+set[i][0]] ) { count++; } } if(count == set.length) {buffer[col][row] = child[r][1][0];} count = 0; } } } } } for (int i=0; i<width; i++) { for(int j=0; j<height; j++) { cells [i][j] = buffer [i][j]; // new = old } } } Iteration2( int w, int h){ width = w; height = h; cells = new int[w][h]; buffer = new int[w][h]; } }
Thanks.
- 07-02-2011, 03:55 AM #10
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
To get started, you will need to click on any random cells on the grid shown, press 1-step, a pattern will start populating.
continous 1-step clicks will move the pattern vertically on a column.
Now if you press the start button, you might see a few of the colums to the left of the screen do not populate every time. That is the problem.
-
I haven't gone through all of your code, but I can see off the bat that you're calling while (true) {...} in the EDT so I'm not surprised that it's not working well. Solution: don't do this -- don't have your game loop written this way. Either use a Swing Timer or do this type of loop off of the EDT.
- 07-02-2011, 02:27 PM #12
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
I used the SwingWorker class to do the tasks in the background, but it is still giving me the same problem. The problem improved somewhat when I synchronized all the methods relating to the update.
Java Code:else if( ev.getSource() == startButton ){ // start running running = true; worker = new SwingWorker(){ @Override protected Object doInBackground() throws Exception { doWork(); return "Work done"; } }; worker.execute(); }Java Code:public synchronized void doWork(){ long delayTime = 1000/FPS; // main loop long startTime, waitTime, elapsedTime; while( !Thread.interrupted() ){ if( running ){ startTime = System.currentTimeMillis(); exchanges.update(); elapsedTime = System.currentTimeMillis() - startTime; waitTime = Math.max( delayTime - elapsedTime, 5 ); try{ Thread.sleep(waitTime); }catch (InterruptedException ie) {} da.repaint(); } } }
- 07-02-2011, 02:30 PM #13
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
My question is, will it help if I use a Swing Timer on this instead of thread.sleep()?
Is there some basic function in java that will make the thread wait till the update() function is entirely complete before proceeding to repaint?
The thread should go like this, update, repaint, update, repaint, update, repaint....so on, till i tell it to stop.
- 07-02-2011, 04:09 PM #14
Do you want a wait time between calls to update()?
Or do you want it called as soon as the painting has finished?
- 07-02-2011, 05:59 PM #15
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
the waitTime is actually just so that it doesn't all happen so fast we can't see the pattern development.
So I want the update() and repaint() functions to do their job separately, without sharing their information at the same time. Which I think is what is happening. I got the best results(least errors) without using SwingWorker, and with synchronizing every method that handled arrays.
Any help?
- 07-02-2011, 06:05 PM #16
So you do need some waitTime > 0waitTime is actually just so that it doesn't all happen so fast we
What is supposed to happen? Does the pattern move to other columns beside the ONE column that is clicked on?see the pattern development.
- 07-02-2011, 06:41 PM #17
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
Suppose i click some cell, now it will start spreading outward vertically, in THAT column. In accordance with a set of rules defined by Stephen Wolfram in his book A New Kind of Science.
Now if i click on say all the cells in a row, they will all show the same pattern.
But in my program, the first couple of cells do not do that, they remain blank, ie the primary colour blue.
The problem that I have located is that somehow, by the time the repaint function starts executing, the EDT hasn't let go of the arrays, so the information is not yet available to the repaint() function. How can I ensure that this info is free and available?
- 07-02-2011, 06:47 PM #18
This is what I just tried:
I selected 20 cells on one row starting at the first column.
I clicked Start.
The display changed to show the first 20 columns on for different rows thru some pattern.
It continued showing the 20 columns in different rows again and again.
I changed my version to use a Timer.
I also added code to make testing easier:
Now could you give me some code that would fill in enough cells to demonstrate the problem so I don't have to manually select some?Java Code:// For testing File dataF = new File("wolfram3.data"); //<<<<<<<<<<<< loadData(dataF); .... //--------------------------------------------------- private void loadData(File dataFile) { try{ FileInputStream fis = new FileInputStream( dataFile ); ObjectInputStream ois = new ObjectInputStream( fis ); exchanges.set=(int[][])ois.readObject(); exchanges.rules = (int[][][])ois.readObject(); exchanges.child = (int[][][])ois.readObject(); fis.close(); }catch( Exception e ){ System.out.println("Error Opening file: " + dataFile.getName() ); e.printStackTrace(); } System.out.println("data loaded"); }
- 07-02-2011, 06:54 PM #19
Member
- Join Date
- Jun 2011
- Location
- Tsukuba, Japan
- Posts
- 63
- Rep Power
- 0
Dear Norm,
I will certainly do that, but didn't you get any cells in the first or second colums as blanks? Meaning, when the pattern was evolving, you could see the green cells on the 2nd, 3rd, 4th columns, but not on the 1st?
Or something like that?
- 07-02-2011, 07:05 PM #20
Similar Threads
-
One row help with Locking Java to MAC Adress
By Darkbound in forum New To JavaReplies: 1Last Post: 04-28-2011, 07:42 PM -
Threading: Locking an object?
By MatuX in forum Threads and SynchronizationReplies: 12Last Post: 06-13-2010, 01:14 PM -
locking strategies
By jicxicmic in forum JDBCReplies: 0Last Post: 09-03-2009, 11:36 PM -
Row level locking........
By jithan in forum New To JavaReplies: 0Last Post: 09-02-2008, 07:09 AM -
row level locking
By jithan in forum New To JavaReplies: 1Last Post: 08-28-2008, 06:42 PM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks