java - stopping threads and where to use locks -
my problem use locks on these threads. when have circles race eachother, when 1 reaches end program should stop , declare winner. instead, finishes of circles finish line, believe due them sharing same lock , maybe resources.
here 3 of classes. appreciated.
import java.awt.borderlayout; import java.awt.event.actionevent; import java.awt.event.actionlistener; import javax.swing.jframe; import javax.swing.jpanel; import javax.swing.jbutton; import java.awt.gridlayout; public class horsepanel extends jframe { private jpanel panel; private jbutton reset; private jbutton quit; private jbutton run; private actionlistener listener; public static final int frame_width = 500; public static final int frame_height = 400; private trackpane trackpane; public horsepanel(trackpane t) { trackpane = t; createpanel(); createrunrace(); createquit(); setsize(frame_width, frame_height); } public void createrunrace() { class runrace implements actionlistener { public void actionperformed(actionevent rightevent) { run.setenabled(false); trackpane.start(); } } actionlistener = new runrace(); this.run.addactionlistener(a); } public void createquit() { class quitrace implements actionlistener { public void actionperformed(actionevent rightevent) { system.exit(0); } } actionlistener b = new quitrace(); this.quit.addactionlistener(b); } public void createreset() { class resetrace implements actionlistener { public void actionperformed(actionevent rightevent) { //trackpane.resetcoordinates; run.setenabled(true); } } actionlistener c = new resetrace(); this.reset.addactionlistener(c); } public void createpanel() { panel = new jpanel(new borderlayout()); trackpane = new trackpane(); this.run = new jbutton("run race"); this.quit = new jbutton("quit"); this.reset = new jbutton("reset"); jpanel toppanel = new jpanel(); toppanel.setlayout(new gridlayout(1, 3)); toppanel.add(run); toppanel.add(reset); toppanel.add(quit); panel.add(toppanel, borderlayout.north); panel.add(trackpane, borderlayout.center); add(panel); } } import javax.swing.jframe; public class horsetester { public static trackpane t = new trackpane(); public static void main(string[] args) { new horsetester(); } public horsetester() { jframe frame = new horsepanel(t); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.setvisible(true); } } import java.awt.graphics; import java.awt.graphics2d; import java.util.concurrent.locks.lock; import java.util.concurrent.locks.reentrantlock; import javax.swing.jframe; import javax.swing.joptionpane; public class horsethread implements runnable { public static final int x_start = 10; public static final int y_start = 20; private boolean running = true; public int finish_line = 450; private horse horse; private int xpos, ypos; private trackpane track; public jframe frame = new jframe(); public int id; public horsethread(trackpane track, int offset) { xpos = x_start; id = offset; // spaces horses apart ypos = y_start * offset * 3; horse = new horse(xpos, ypos); this.track = track; } public void paint(graphics g) { graphics2d g2 = (graphics2d) g; horse.draw(g2); } /** * run method thread executes , makes horses go across screen * racing. */ public void run() { while (running) { //varying x position movement horse.setx(xpos += (int) (math.random() * 10 + 1), id); // sleeping thread track.repaint(); try { thread.sleep(100); } catch (interruptedexception e) { e.printstacktrace(); } if (xpos >= finish_line) { running = false; } } } } public class horse { private int xtop, xstart; private int ytop, ystart; public static final int ring_width = 20, finish_line=450; public jframe frame = new jframe(); public lock lockthing = new reentrantlock(); public horse(int x, int y) { xtop = x; ytop = y; xstart = x; ystart = y; } public void setx(int dx, int id) { try{ lockthing.lock(); xtop=dx; if (dx >= finish_line){ joptionpane.showmessagedialog(frame, id + " won"); } }finally{ lockthing.unlock();} } public void draw(graphics2d g2) { ellipse2d.double horse = new ellipse2d.double(xtop, ytop, ring_width, ring_width); g2.setcolor(color.red); g2.fill(horse); g2.setcolor(color.blue); g2.draw(horse); } } public class trackpane extends jpanel { private static final int num_of_horses = 5; private arraylist<horsethread> horses = new arraylist<horsethread>(); private arraylist<thread> threads = new arraylist<thread>(25); public trackpane() { setbackground(color.white); reset(); } public void reset() { // should dispose of running threads... horses.clear(); // allocating memory horses (int = 0; < num_of_horses; i++) { horses.add(new horsethread(this, + 1)); } } public void start() { // should dispose of running threads... threads.clear(); (int = 0; < horses.size(); i++) { thread thread = new thread(horses.get(i)); thread.start(); threads.add(thread); } } @override protected void paintcomponent(graphics g) { super.paintcomponent(g); (horsethread horse : horses) { horse.paint(g); } } }
you need share running variable between threads
private boolean running = true;
the fastest way (but not best one) changing static:
private static volatile boolean running = true;
the more proper , blessed way creating component shared between threads , take care of synchronization. thing messing around pop ups:
joptionpane.showmessagedialog(new jframe(), id + " won");
which blocking thread until closes them , preventing thread setting running false. move logic run method of horsethread , remove setx method in horse class:
class horsethread implements runnable { private static volatile boolean running = true; public static final int x_start = 10; public static final int y_start = 20; public int finish_line = 450; private horse horse; private int xpos, ypos; private trackpane track; public jframe frame = new jframe(); public int id; public horsethread(trackpane track, int offset) { xpos = x_start; id = offset; // spaces horses apart ypos = y_start * offset * 3; horse = new horse(xpos, ypos); this.track = track; } public void paint(graphics g) { graphics2d g2 = (graphics2d) g; horse.draw(g2); } /** * run method thread executes , makes horses go across screen * racing. */ public void run() { while (running) { //varying x position movement horse.setx(xpos += (int) (math.random() * 10 + 1), id); // sleeping thread track.repaint(); try { thread.sleep(100); } catch (interruptedexception e) { e.printstacktrace(); } if (xpos >= finish_line) { running = false; joptionpane.showmessagedialog(new jframe(), id + " won"); } } } } class horse { private int xtop, xstart; private int ytop, ystart; public static final int ring_width = 20, finish_line=450; public jframe frame = new jframe(); public lock lockthing = new reentrantlock(); public horse(int x, int y) { xtop = x; ytop = y; xstart = x; ystart = y; } public void setx(int dx, int id) { try{ lockthing.lock(); xtop=dx; }finally{ lockthing.unlock();} } public void draw(graphics2d g2) { ellipse2d.double horse = new ellipse2d.double(xtop, ytop, ring_width, ring_width); g2.setcolor(color.red); g2.fill(horse); g2.setcolor(color.blue); g2.draw(horse); } }
Comments
Post a Comment