Jump to content

So my program works, you can copy these 4 classes in eclipes and try it yourself. However the program i using 70% of my CPU! That's crazy ! 

 

It's repainitng everything I know. I tried to make the thread pause but it's just not working. I'm not sure how the make the thread pause when doorl =5 (the door is open which means it has no reason to repaint)

 

Design.java

import java.awt.Color;import java.awt.Graphics;import javax.swing.JFrame;import javax.swing.JPanel;public class Design extends JFrame implements Runnable{	private static final long serialVersionUID = 1L;		Canvas canvas = new Canvas();	public static boolean refresh = false;	static public Elevator elevator = new Elevator(250, 280);	static public Elevator elevator2 = new Elevator(1250, 280);	static int cloudx=0;		public Design () {		this.setLayout(null);		this.add(elevator);		this.add(elevator2);		int k = 4;		for(int i=0; i<=450; i+=150){			this.add(new Window(250, 280+i,"L", k));			k--;		}		k=4;		for(int i=0; i<=450; i+=150){			this.add(new Window(1250, 280+i,"R", k));			k--;		}		this.add(canvas); 		this.setVisible(true);		this.setSize(1600,1000);		this.setLocationRelativeTo(null);		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);		this.setBackground(new Color(168,186,186));		this.setResizable(false);		Thread t = new Thread(this);		t.start();	}		class Canvas extends JPanel{		/**		 * 		 */		private static final long serialVersionUID = 1L;		int width;		int height;				public Canvas(){			width = getSize().width;			height = getSize().height;			setBounds(0,0,1600,1000);		}				public void paintComponent(Graphics g){			//clouds			g.setColor(Color.WHITE);			g.fillOval(500-cloudx, 100, 200, 100);			g.fillOval(640-cloudx, 100, 170, 70);			g.fillOval(400-cloudx, 100, 170, 70);			g.fillOval(1000-cloudx, 300, 200, 100);			g.fillOval(1140-cloudx, 300, 170, 70);			g.fillOval(900-cloudx, 300, 170, 70);						g.fillOval(1500-cloudx, 100, 200, 100);			g.fillOval(1640-cloudx, 100, 170, 70);			g.fillOval(1400-cloudx, 100, 170, 70);						//birds			g.setColor(Color.BLACK);			g.drawArc(1000, 100, 50, 20, 0, 180);			g.drawArc(1050, 100, 50, 20, 0, 180);						g.drawArc(1100, 50, 50, 20, 0, 180);			g.drawArc(1150, 50, 50, 20, 0, 180);						//foundation			int x[] = {200, 200, 1400, 1400, 					1450, 1450, 1150, 1150, 1200, 1200, 					1150, 1150, 1100, 1100, 1050, 1050, 1000,					1000, 950, 950, 650, 650, 600, 600, 550, 550,					500, 500, 450, 450, 400, 400, 450, 450,					150, 150, 200};			int y[] = {400, 900, 900, 400, 					350, 250, 250, 350, 400, 500, 					500, 450, 450, 500, 500, 450, 450,					500, 500, 350, 350, 500, 500, 450, 450, 500,					500, 450, 450, 500, 500, 400, 350, 250,					250, 350, 400};			g.setColor(new Color(233,234,226));			g.fillPolygon(x, y, x.length); 			g.setColor(Color.GRAY);			g.drawPolygon(x, y, x.length);			g.setColor(new Color(68,11,2));						int c1x[] = {150, 300, 450};			int c1y[] = {250, 100, 250};			g.fillPolygon(c1x, c1y, c1x.length); 						int c2x[] = {1450, 1300, 1150};			int c2y[] = {250, 100, 250};			g.fillPolygon(c2x, c2y, c2x.length);						int c3x[] = {950, 800, 650};			int c3y[] = {350, 200, 350};			g.fillPolygon(c3x, c3y, c3x.length);						//sun			g.setColor(Color.YELLOW);			g.fillOval(1450,-100,200,200);						//ground			g.setColor(Color.GREEN);			g.fillRect(0,900,1600,100);						//pathway			g.setColor(new Color(255, 170, 130));			int z[] = {700, 900, 1000, 600};			int t[] = {900, 900, 1000, 1000};			g.drawPolygon(z, t, z.length);			g.fillPolygon(z, t, z.length); 						//door					g.setColor(new Color(68,11,2));			g.fillArc(700, 750, 200, 100, 0, 180);			g.fillRect(700, 800, 200, 100);					}	}	@[member=OverRide]	public void run() {		while(refresh)			if(elevator.doorl>=5){				this.repaint();			}	}	}

Window.java

import java.awt.Color;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JPanel;public class Window extends JPanel implements ActionListener{	private static final long serialVersionUID = 1L;			public JButton button;		public int x, y;		String no;			public Window (int x, int y, String no, int floor){		this.x = x;		this.y = y;		setBounds(x,y,200,100);		button = new JButton(no+floor);		setLayout(null);		add(button);		button.setBounds(100, 50, 30,30);		button.setBorder(null);		button.setBackground(Color.YELLOW);		button.addActionListener(this);		this.no = no;	}		public void paintComponent(Graphics g){		g.setColor(new Color(68,11,2));		g.fillRect(0, 0, 100, 100);			}		@[member=OverRide]	public void actionPerformed(ActionEvent Evt) {		Object source = Evt.getSource (); 		if (source == button){			if(no == "L"){				Design.elevator.x = x;				Design.elevator.y = y-280;						}			if(no == "R"){				Design.elevator2.x = x;				Design.elevator2.y = y-280;			}		}	}}

Elevator.java

import java.awt.Color;import java.awt.Graphics;import javax.swing.JPanel;public class Elevator extends JPanel implements Runnable{	private static final long serialVersionUID = 1L;	public int currx, curry, x, y, floor;	public int doorl=50, doory=50;	boolean openDoor = true;	boolean closeDoor = false;	boolean busy = false;	public String no;	Thread t;		public Elevator(int x, int y){		setBounds(x, y, 680, 550);		currx = 0;		curry = 0;		this.x=0;		this.y=0;			t = new Thread(this);		t.start();	}		public void paintComponent(Graphics g){			g.setColor(new Color(68,11,2));		g.fillRect(currx+0, curry+0, 100, 100);		g.setColor(Color.orange);		for(int i=0;i<5;i++){			g.drawRect(currx+i, curry+i, 100-2*i, 100-2*i);		}		g.drawLine(currx+50,curry,currx+50,curry+100);				g.setColor(Color.YELLOW);		for(int i=50; i>=doorl; i--)			g.drawLine(currx+i,curry+5,currx+i,curry+95);		for(int i=50; i<=doory; i++)			g.drawLine(currx+i,curry+5,currx+i,curry+95);				}	@[member=OverRide]	public void run() {		while(true){				try{					Design.refresh = true;								if(y!=curry){						if(closeDoor){							while(doorl<50 && doory>50){								doorl++;								doory--;								Thread.sleep(30);								this.repaint();							}						}						if(y>curry){							while(y>curry){							curry++;							Thread.sleep(10);							this.repaint();							}						} else {							while(y<curry){							curry--;							Thread.sleep(10);							this.repaint();							}						}					}					if(y == curry){						if(openDoor){							while(doorl>5 && doory<95){								doorl--;								doory++;								Thread.sleep(30);								this.repaint();							}						}					}										if(doorl==5){						openDoor = false;						closeDoor = true;					} 										if(doorl==50){						closeDoor = false;						openDoor = true;					}									} catch(InterruptedException e){					System.out.println(e.getMessage());				}		}	}}

main.java

public class Main {	public static void main (String args[]){		new Design();			}}
Link to comment
https://linustechtips.com/topic/524553-thread-using-too-much-power-java/
Share on other sites

Link to post
Share on other sites

I like how one of your variables is called curry..... but seriously, it looks like you're repainting pretty often, which would explain the high CPU usage, which isn't really a problem - it's expecting. However, another reason might just be because Java isn't a very fast language - if you're making a completely custom GUI or game or whatever, you might want to look into lwjgl, which you can use to have OpenGL, a powerful graphics library, in Java.

Pro Tip: don't use flash when taking pictures of your build; use a longer exposure instead. Prop up your camera with something (preferably a tripod) if necessary.

if you use retarded/autistic/etc to mean stupid please gtfo

Link to post
Share on other sites

In design.run change the code to:

    @[member='OverRide']    public void run() {        while(refresh)            if(elevator.doorl>=5){                this.repaint();            }            try {                Thread.sleep(16);//60hz            }catch(Exception e) {}    }

Even when you don't need to repaint you are constantly checking the doorl to see if you actually do need to repaint, so that thread will always be at 100% usage whether its repainting or not. More than that the repaint is actually asynchronous, its a signal to redraw so the big problem is even though my change will reduce the impact you are still going to redraw 60 times a second even if you don't need to. You should consider an event architecture instead where you detect if you need to redraw and then do so, that is how Swing works internally and you should adopt their architecture for your components as well.

 

You need to do similar changes in Elevator as well because currently there are plenty of loops that just continuously check variables and it avoids the Thread.sleeps. Do it at the top level along with the loop itself so that you avoid just churning on the CPU checking things. But to be honest its not solving the issue which is that the main thread which runs swing is being blocked, this code just doesn't work the way you think it does, you need a different architecture.

Link to post
Share on other sites

I like how one of your variables is called curry..... but seriously, it looks like you're repainting pretty often, which would explain the high CPU usage, which isn't really a problem - it's expecting. However, another reason might just be because Java isn't a very fast language - if you're making a completely custom GUI or game or whatever, you might want to look into lwjgl, which you can use to have OpenGL, a powerful graphics library, in Java.

 

This is my java college project, I am forced to draw it and use it in this way with threads.

Link to post
Share on other sites

In design.run change the code to:

    @[member='OverRide']    public void run() {        while(refresh)            if(elevator.doorl>=5){                this.repaint();            }            try {                Thread.sleep(16);//60hz            }catch(Exception e) {}    }

Even when you don't need to repaint you are constantly checking the doorl to see if you actually do need to repaint, so that thread will always be at 100% usage whether its repainting or not. More than that the repaint is actually asynchronous, its a signal to redraw so the big problem is even though my change will reduce the impact you are still going to redraw 60 times a second even if you don't need to. You should consider an event architecture instead where you detect if you need to redraw and then do so, that is how Swing works internally and you should adopt their architecture for your components as well.

 

You need to do similar changes in Elevator as well because currently there are plenty of loops that just continuously check variables and it avoids the Thread.sleeps. Do it at the top level along with the loop itself so that you avoid just churning on the CPU checking things. But to be honest its not solving the issue which is that the main thread which runs swing is being blocked, this code just doesn't work the way you think it does, you need a different architecture.

 

Tried yours, did calm down the CPU a bit .. but nothing noticeable. Thing is I tried doing something.. I put in the if(doorl==5){ Design.refresh  = false;},.. but it will always remain false... no matter if doorl changed I don't know why ... When it reaches doorl = 5.. It stops refreshing and my cpu is abrely using 1%.. but when i click on any button and the elevator moves, the window is messed up and everything looks on top of each other and just wrong.. I'm trying to refresh = false in elevator but it will just always remain false.

Link to post
Share on other sites

I suspect you have a busy waiting problem. The reason for the threads should be to eliminate that, but you then need to ensure that if any shared variables are used, none of the threads can change or update something before it's task is complete, because there's no guarantee which thread will complete first.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×