这是我第一次做多线程而且我有点坚持如何创建两个线程,“Reader”线程和“Writer”线程只在单击JButton“jbStart”时执行?我不能把run()方法放在actionPerformed()中,因为它不会正确运行,我也不能在其中添加thread.start(),它必须是一个静态的main方法,除非我'我错了纠正我。现在,整个代码按原样运行。为了进一步了解,它只是一个Target Finder程序,您可以在其中输入Max#(要生成的最大随机数 - 例如:Max#= 100,随机数将生成0到100之间的任何值),Target #(要查找的目标编号以及在ms中花费的时间。)缓冲区只读取JTextArea。
“读者”主题 -reader在找到目标#时停止并正确显示时间。
“作家”主题 -writer使用max#。
生成随机数我真正的问题是我如何将这两个线程混合在一起,我已经尝试过添加sleep,interrupt,notify,signalAll等...但是我只是不知道该把它放到哪里才能让它正常工作。希望你们能告诉我这个程序是如何工作的,我很乐意从中学习并掌握线程如何工作的知识。这是代码:
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.util.Random;
public class TargetFinder extends JFrame implements ActionListener
{
//GUI attributes
JLabel jlMax, jlTarget, jlBuffer;
JTextField jtfMax, jtfTarget, jtfBuffer;
JTextArea txtArea;
JScrollPane jsp;
JButton jbStart, jbReset, jbExit;
JPanel pnl1, pnl2, nPnl, sPnl;
int isIntegerMax, isIntegerTarget;
String isStringMax, isStringTarget;
public TargetFinder()
{
//create frame
setLayout(new BorderLayout());
//create content
/*-------------------------------NORTH-------------------------------*/
jlMax = new JLabel("Max #");
jtfMax = new JTextField(7);
jlTarget = new JLabel("Target #");
jtfTarget = new JTextField(7);
jlBuffer = new JLabel("Buffer");
jtfBuffer = new JTextField(7);
jtfBuffer.setEditable(false);
//create panel and add contents to it
pnl1 = new JPanel();
pnl1.add(jlMax);
pnl1.add(jtfMax);
pnl1.add(jlTarget);
pnl1.add(jtfTarget);
pnl1.add(jlBuffer);
pnl1.add(jtfBuffer);
nPnl = new JPanel();
nPnl.add(pnl1);
add(nPnl,"North"); //add the panel to the North on the JFrame
/*-------------------------------CENTER-------------------------------*/
txtArea = new JTextArea(25,60);
txtArea.setLineWrap(true);
txtArea.setWrapStyleWord(true);
txtArea.setEditable(true);
jsp = new JScrollPane(txtArea);
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
add(jsp,"Center"); //add JScrollPane to the JTextArea where as-is
/*-------------------------------SOUTH-------------------------------*/
jbStart = new JButton("Start");
jbStart.setMnemonic('S');
jbReset = new JButton("Reset");
jbReset.setMnemonic('R');
jbExit = new JButton("Exit");
jbExit.setMnemonic('x');
//create panel and add contents to it
pnl2 = new JPanel();
pnl2.add(jbStart);
pnl2.add(jbReset);
pnl2.add(jbExit);
sPnl = new JPanel();
sPnl.add(pnl2);
add(sPnl, "South"); //add the panel to the South on the JFrame
//ActionListener Registration
//jtfMax.addActionListener(this);
//jtfTarget.addActionListener(this);
//jtfBuffer.addActionListener(this);
jbStart.addActionListener(this);
jbReset.addActionListener(this);
jbExit.addActionListener(this);
//GUI properties
setTitle("Target Finder");
setLocation(200,200);
setSize(700,500);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack(); //resize window to fit
}
public void actionPerformed(ActionEvent ae)
{
//checks user input of jtfMax and jtfTarget
if(ae.getSource() == jbStart)
{
/*------------------------MAX #------------------------*/
try
{
isStringMax = jtfMax.getText(); //get the text of Max #
isIntegerMax = 0;
isIntegerMax = Integer.parseInt(isStringMax); //convert from String to int
if(isIntegerMax < 0) //if the value is negative
{
JOptionPane.showMessageDialog(null,"Please enter a positive number", "Max #", JOptionPane.INFORMATION_MESSAGE);
}
}
catch(NumberFormatException nfe)
{
if(jtfMax.getText().isEmpty())
{
JOptionPane.showMessageDialog(null,"Please enter a positive number", "Max #", JOptionPane.INFORMATION_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(null,"You entered: " + isStringMax + "\nPlease enter a positive number",
"Max #", JOptionPane.INFORMATION_MESSAGE);
}
}
/*------------------------TARGET #------------------------*/
try
{
isStringTarget = jtfTarget.getText(); //get the text of Target #
isIntegerTarget = 0;
isIntegerTarget = Integer.parseInt(isStringTarget); //convert from String to int
if(isIntegerTarget < 0) //if the value is negative
{
JOptionPane.showMessageDialog(null,"Please enter a positive number",
"Target #", JOptionPane.INFORMATION_MESSAGE);
}
}
catch(NumberFormatException nfe)
{
if(jtfTarget.getText().isEmpty())
{
JOptionPane.showMessageDialog(null,"Please enter a positive number", "Target #", JOptionPane.INFORMATION_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(null,"You entered: " + isStringTarget + "\nPlease enter a positive number",
"Target #", JOptionPane.INFORMATION_MESSAGE);
}
}
try
{
if(isIntegerTarget >= isIntegerMax || isIntegerTarget < 0) //if Target # >= Max # (>= avoids a glitch where it freezes the program if Max # = Target #)
{
JOptionPane.showMessageDialog(null,"Please enter a target number < Max #");
}
else
{
//checks both values if can be converted to an int
Integer.parseInt(isStringMax);
Integer.parseInt(isStringTarget);
try
{
Random randomGenerator = new Random(); //create a random object for random numbers
Boolean foundMatch = false; //check when random numbers = Target #
final long startTime = System.currentTimeMillis(); //start of the program's execution time in milliseconds
//generates many random numbers until condition is met
while(!foundMatch)
{
int randomInt = randomGenerator.nextInt(isIntegerMax); //generates random numbers up to the value of Max # (isIntegerMax)
String isStringRandom = Integer.toString(randomInt); //convert random numbers to String
txtArea.append(randomInt + " "); //add random numbers to the JTextArea
String isBuffer = Integer.toString(randomInt); //convert randomInt int to String
jtfBuffer.setText(isBuffer);
String isStringTarget = Integer.toString(isIntegerTarget); //convert Target # (isIntegerTarget) to String
//if the Buffer matches the Target #
if(isBuffer.equals(isStringTarget))
{
foundMatch = true;
break;
}
}
final long duration = System.currentTimeMillis() - startTime; //calculate the total time of the program's execution
txtArea.append("\nIt took " + duration + " milliseconds");
txtArea.requestFocus();
}
catch(IllegalArgumentException iae)
{
iae.printStackTrace(); //prints the error messages
return;
}
}
}
catch(NumberFormatException nfe)
{
JOptionPane.showMessageDialog(null, "Either Max # and/or Target # is not a number. Please enter a positive number");
}
}
else if(ae.getSource() == jbReset)
{
//empty all text fields
jtfMax.setText("");
jtfTarget.setText("");
jtfBuffer.setText("");
txtArea.setText("");
jtfMax.requestFocus();
}
else if(ae.getSource() == jbExit)
{
System.exit(0);
}
}
/**
This class implements the first runnable object for the first thread
*/
class Runnable1 implements Runnable
{
public synchronized void run()
{
try
{
Thread.sleep(1);
}
catch(InterruptedException ie)
{
System.out.println("Reader Thread #1 Interrupted!");
}
}
}
/**
This class implements the second runnable object for the second thread
*/
class Runnable2 implements Runnable
{
public synchronized void run()
{
try
{
Thread.sleep(1);
/*------------------------BUFFER------------------------*/
//String isBuffer = Integer.toString(isIntegerTarget); //convert Target # int to String
//jtfBuffer.setText(isBuffer);
/*------------------------RANDOM NUMBER GENERATOR------------------------*/
/*READER THREAD HANDLES THIS*/
/*WRITER THREAD HANDLES THIS*/
/*
try
{
if(isIntegerTarget >= isIntegerMax) //if Target # >= Max # (>= avoids a glitch where it freezes the program if Max # = Target #)
{
JOptionPane.showMessageDialog(null,"Please enter a target number < Max #");
}
else
{
//checks both values if can be converted to an int
Integer.parseInt(isStringMax);
Integer.parseInt(isStringTarget);
try
{
Random randomGenerator = new Random(); //create a random object for random numbers
Boolean foundMatch = false; //check when random numbers = Target #
final long startTime = System.currentTimeMillis(); //start of the program's execution time in milliseconds
//generates many random numbers until condition is met
while(!foundMatch)
{
int randomInt = randomGenerator.nextInt(isIntegerMax); //generates random numbers up to the value of Max # (isIntegerMax)
String isStringRandom = Integer.toString(randomInt); //convert random numbers to String
txtArea.append(randomInt + " "); //add random numbers to the JTextArea
String isBuffer = Integer.toString(randomInt); //convert randomInt int to String
jtfBuffer.setText(isBuffer);
String isStringTarget = Integer.toString(isIntegerTarget); //convert Target # (isIntegerTarget) to String
//if the Buffer matches the Target #
if(isBuffer.equals(isStringTarget))
{
foundMatch = true;
break;
}
}
final long duration = System.currentTimeMillis() - startTime; //calculate the total time of the program's execution
txtArea.append("\nIt took " + duration + " milliseconds");
txtArea.requestFocus();
}
catch(IllegalArgumentException iae)
{
iae.printStackTrace(); //prints the error messages
return;
}
}
}
catch(NumberFormatException nfe)
{
JOptionPane.showMessageDialog(null, "Either Max # and/or Target # is not a number. Please enter a positive number");
}
*/
}
catch(InterruptedException ie)
{
System.out.println("Writer Thread #2 Interrupted!");
}
}
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
// create the window
TargetFinder targetFinder = new TargetFinder(); //runs the program
// create the writer thread
Runnable r1 = targetFinder.new Runnable1();
Thread t1 = new Thread(r1);
// create the reader thread
Runnable r2 = targetFinder.new Runnable2();
Thread t2 = new Thread(r2);
// start the threads
t1.start();
t2.start();
/*try
{
}
catch(InterruptedException ie)
{
ie.printStackTrace();
return;
}*/
}
});
}
}
答案 0 :(得分:2)
这是我第一次做多线程而且我有点坚持如何创建两个线程,“Reader”线程和“Writer”线程只在单击JButton“jbStart”时执行?
那你为什么要写一个300行程序来测试呢?
为什么不从包含单个JButton的GUI开始,该JButton称为“Start”,在单击时启动Thread。一旦你开始工作,你就可以对你的真实程序进行更改。
这称为创建SSCCE。然后,如果它仍然无法正常工作,您可以在论坛上发布简单的代码。我们没有时间阅读您的所有代码,看看您在做什么。
我不能把run()方法放在actionPerformed()中,因为它不能正确运行
什么不能正确运行?如果它不起作用,那么你没有正确实现Thread。我们不知道您的尝试是什么,所以我们无法给出具体的建议。
我也不能在其中添加thread.start(),它必须是一个静态的main方法,除非我错了纠正我
您不应该使用静态方法。只需将Runnable创建为类变量即可。然后,您可以从类中的任何位置调用start()方法。或者在actionPerformed()方法中定义整个Runnable。