可能重复:
How do I start optimising my Java code? - CPU is at 100%
我有一个方法isReset(),它像疯了一样执行,我把它定义为
public boolean isReset() { return reset;
}
在另一个班级。下面的类是唯一使用此代码的类。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.border.BevelBorder;
import javax.swing.border.SoftBevelBorder;
// TimerQueue
public class SkaTest {
public static final int WIDTH = 500;
public static final int HEIGHT = 500;
public static final int CANVAS_X = 100;
public static final int CANVAS_Y = 100;
public static final int CANVAS_FRAME_WIDTH = WIDTH+100;
public static final int CANVAS_FRAME_HEIGHT = HEIGHT + 100;
public static final int EXEC_WIDTH = 550;
public static final int EXEC_HEIGHT = 400;
static VizDSList dsList = new VizDSList();
static SkaCanvas canvas = new SkaCanvas(dsList);
static JFrame canvasFrame = new JFrame("Data Structure Canvas");
static JMenuBar menuBar = new JMenuBar();
static JMenu algorithmMenu = new JMenu("Algorithm");
static JMenu dsMenu = new JMenu("Create");
static JMenu helpMenu = new JMenu ("Help");
static JLabel status = new JLabel(" ");
static SkaProgram[] alg;
static JFrame execFrame[];
static SkaExecutionPanel execPanel[];
public static void setupFrames(int nAlgs) {
int i;
for (i=0; i < nAlgs; i++) {
// execFrame[i] = new JFrame("Execution Control Panel "+(i+1));
execFrame[i] = new JFrame();
execPanel[i] = new SkaExecutionPanel(execFrame[i]);
}
canvas.setMinimumSize(new Dimension(WIDTH, HEIGHT));
canvasFrame.setSize(CANVAS_FRAME_WIDTH, CANVAS_FRAME_WIDTH);
canvasFrame.getContentPane().setLayout(new BorderLayout(10,7));
// canvasFrame.getContentPane().setPreferredSize(new Dimension(WIDTH, HEIGHT));
canvasFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// canvas.setMinimumSize(new Dimension(WIDTH, HEIGHT));
for (i=0; i < nAlgs; i++) {
execFrame[i].setSize(EXEC_WIDTH, EXEC_HEIGHT);
// execFrame[i].getContentPane().setLayout(new BorderLayout(10,7));
execFrame[i].addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
execPanel[i].setBorder(new SoftBevelBorder(BevelBorder.RAISED));
// execFrame[i].setContentPane(execPanel[i]);
execFrame[i].getContentPane().add("Center", execPanel[i]);
// execFrame[i].setLocation(CANVAS_X +CANVAS_FRAME_WIDTH, CANVAS_Y + i*EXEC_HEIGHT);
execFrame[i].setLocation(CANVAS_X +CANVAS_FRAME_WIDTH + i*30, CANVAS_Y + i*50);
}
canvas.setBorder(new SoftBevelBorder(BevelBorder.RAISED));
canvasFrame.getContentPane().add("Center", new JScrollPane(canvas) );
// canvasFrame.getContentPane().add("Center", new JScrollPane(canvas, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS) );
canvasFrame.getContentPane().add("South", status);
canvasFrame.setLocation(CANVAS_X, CANVAS_Y);
JMenu fileMenu = new JMenu("File");
JMenuItem quitItem = new JMenuItem("Quit");
//TODO Add quit listener
quitItem.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent arg0) {
//System.exit(0);
int again = JOptionPane.showConfirmDialog(null, "Are you sure you want to exit system", "Exiting", JOptionPane.YES_NO_OPTION);
if (again == JOptionPane.YES_OPTION)
{
System.exit(0);
}
}
}
);
fileMenu.add(quitItem);
menuBar.add(fileMenu);
menuBar.add(algorithmMenu);
// menuBar.add(dsMenu);
menuBar.add(helpMenu);
JMenuItem help = new JMenuItem ("Help Contents");
//help.setMnemonic(KeyEvent.VK_H);
//TODO Fix this method
help.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, ActionEvent.CTRL_MASK));
help.addActionListener(new ActionListener()
{
/*
@Override
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(null, "Alot of the functionality have not yet been included in this version\nCurrently working on the automation features now!", "SKA 0.2 Beta", JOptionPane.WARNING_MESSAGE);
}
*/
public void actionPerformed(ActionEvent arg0) {
try {
Runtime.getRuntime().exec("hh.exe C:/ska.chm");
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "File not found", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
JMenuItem about = new JMenuItem ("About SKA");
about.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(null, "SKA Version 0.1 Beta");
}
});
helpMenu.add(help);
helpMenu.add(about);
canvasFrame.setJMenuBar(menuBar);
}
/** The create menu item */
public static void createProgram(int i) {
JMenuItem algItem;
switch (i) {
case 0 :
alg[0] = new RedBlackValidate(canvas, execPanel[0]);
execFrame[0].setTitle("Validate Algorithm");
System.out.println("Validate Algorithm");
algItem = new JMenuItem("Validate Algorithm");
algorithmMenu.add(algItem);
break;
default:
break;
}
}
public static void main(String args[]) {
int i, nAlgs = 1; //nAlgs = 7;
alg = new SkaProgram[nAlgs];
execPanel = new SkaExecutionPanel[nAlgs];
execFrame = new JFrame[nAlgs];
// canvas.setDebugGraphicsOptions(DebugGraphics.BUFFERED_OPTION);
setupFrames(nAlgs);
canvasFrame.setVisible(true);
for (i=0; i < alg.length; i++) {
createProgram(i);
execFrame[i].setVisible(true);
alg[i].start();
alg[i].displayAlgorithm();
}
while (true) {
for (i=0; i < alg.length; i++)
if (execPanel[i].isReset()) {
alg[i].terminate();
createProgram(i);
alg[i].start();
execPanel[i].unreset();
}
}
}
} // End class SkaTest
答案 0 :(得分:5)
isReset
没有错,但是这个循环不会只是一遍又一遍地调用它(以及一遍又一遍......)?
while (true) {
for (i=0; i < alg.length; i++)
if (execPanel[i].isReset()) {
alg[i].terminate();
createProgram(i);
alg[i].start();
execPanel[i].unreset();
}
}
如果没有别的,你可以在那里拍一个Thread.yield()
来强制线程定期放弃它的时间片,这样就不会占用CPU。
最好放弃轮询,而是使用基于监听器的方法。允许execPanel
在重置时通知侦听器,而不是反复询问一个循环是否重置。这段代码相当于“我们还有吗?我们还有吗?我们还在吗?”
您可能还会将听众称为observers。如果你四处寻找有关这个design pattern的更多信息,那么很多好的信息都会出现在这两个术语中。
以下是您可以重写代码以使用侦听器概念的方法。我为这段代码中的任何错误道歉,我没有编译它。尽管代码中可能存在任何错误,但希望这些想法很清楚。
如果代码没有意义,请查看上面的链接。或者你可以使用EventListener
s来玩,当你进行Swing GUI编程时,你会一直使用它。
public class SkaExecutionPanel {
// Anybody who wants to be told when a panel is reset will implement
// this interface and call addListener().
public interface Listener {
void panelReset(SkaExecutionPanel panel);
}
// Each panel needs to maintain an internal list of listeners.
private List<Listener> listeners = new ArrayList<Listener>();
public void addListener(Listener listener) {
listeners.add(listener);
}
public void removeListener(Listener listener) {
listeners.remove(listener);
}
public void reset() {
/* Do your thing. */
// When something happens that the listeners will care about, such as a
// call to reset() in this case, you iterate through the list and tell
// each one what's happened.
for (Listener listener: listeners) {
listener.panelReset(this);
}
}
}
public class SkaTest {
public static void main(String args[]) {
/* Snippety snip. */
for (i=0; i < alg.length; i++) {
// Here we need to tell the execPanels that we want to do something
// whenever somebody calls reset() on them. We will add a listener
// to each panel that does the terminate/createProgram/start dance.
// This way we don't have to ask the panels when they are reset;
// instead they will tell us when that happens.
execPanel[i].addListener(new SkaExecutionPanel.Listener() {
final int index = i;
public void panelReset(SkaExecutionPanel panel) {
alg[index].terminate();
createProgram(index);
alg[index].start();
execPanel[index].unreset();
}
});
}
}
}
答案 1 :(得分:2)
在您添加此信息后,这是从编辑到我对您的第一个问题的回答:
“编辑:while循环是一个无限循环,导致for循环运行,其中已检查数组中的每个项目是否已重置。您可以使用观察者模式替换它,其中重置对象时,它通知观察对象然后执行那组步骤。这样你就没有无限循环,你减少了.isReset()的用法。“
编辑:其他答案的问题在于,在我看来,使用无限循环会产生一些代码味道。
编辑2:这是wikipedia article的示例。