这是我第一次做多线程,我有点纠结于如何让两个线程,“Reader”线程和“Writer”线程仅在单击 JButton“jbStart”时执行?我不能将 run() 方法放在 actionPerformed() 中,因为它不能正确运行,我也不能在其中添加 thread.start(),它必须在静态 main 方法中,除非我'我错了纠正我。现在,整个代码按原样运行。为了进一步了解,它只是一个 Target Finder 程序,您可以在其中输入 Max #(要生成的最大随机数 - 例如:Max # = 100,随机数将在 0 - 100 之间生成),Target # (要找到的目标编号以及花费的时间(以毫秒为单位)。)缓冲区只是读取 JTextArea。
“Reader” Thread -reader 在找到目标 # 并正确显示时间时停止。
"Writer" Thread -writer 使用最大 # 生成随机数。
我真正的问题是如何将这两个线程与此混合,我已经尝试添加睡眠、中断、通知、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;
}*/
}
});
}
}