gpt4 book ai didi

java - 如何对java中ExecutorService内部的相似线程求和?

转载 作者:行者123 更新时间:2023-12-01 21:10:44 24 4
gpt4 key购买 nike

我正在尝试对 ExecutorService 内的类似线程进行求和。我认为我应该使用 join() 方法,但我无法正确执行。

我的代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Gui extends JFrame implements ActionListener{
private JTextField txtSeats, txtAgents, txtTime;
public int numFirst, numSecond, numThird;
private JTextArea [] bookSeat;
private JButton btn1, btn2;
private String output, name;
private Random ran;
private JPanel p1, p2;
private String [] agentNumber;
private int [] sum;
private int x, z;

public Gui() {//A constructor for the Gui class.

ran = new Random();//Initializing the Random class.


setLayout(new BorderLayout());//Setting the layout for the JFrame.
setTitle("");//the title of the program.


p1 = new JPanel();//Creating the first JPanel to add JButtons and JTextField on it.
p1.setLayout(new FlowLayout());//Setting the first JPanel's layout.


//Creating 3 JTextField with a title for each, and adding each of them to the first JPanel.
txtSeats = new JTextField("Number of seats");
p1.add(txtSeats);

txtAgents = new JTextField("Number of agents");
p1.add(txtAgents);

txtTime = new JTextField("Max waiting time");
p1.add(txtTime);


//Creating 2 JButton with a title for each, and adding each of them to the first JPanel.
btn1 = new JButton("Create seats");
p1.add(btn1);

btn2 = new JButton("Book");
p1.add(btn2);


//Registering the 2 JButton to the ActionListener so they work with the actionPerformed() method when they get clicked.
btn1.addActionListener(this);
btn2.addActionListener(this);


add(p1, BorderLayout.NORTH);//Adding the first JPanel to the main JFrame at the position NORTH.


//Giving some properties to the JFrame layout.
setExtendedState(JFrame.MAXIMIZED_BOTH);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
}//End of the constructor.



public void createSeat() {//A method for creating a number of empty seats depending on the users wish.

//Storing the value of the first JTextField into an integer variable.
//With removing the spaces in it if there is any using "trim()".
numFirst = Integer.parseInt(txtSeats.getText().trim());


//Creating a JTextArea array for the number of seats the user wants to add.
//The size is entered by the user.
bookSeat = new JTextArea[numFirst];


p2 = new JPanel(); //Creating the second JPanel to add JTextArea on it.
p2.setLayout(new FlowLayout()); //Setting the second JPanel's layout.


//for-loop for adding the new JTextArea array into the second JPanel.
//With setting their title and background color and other properties.
for(int i = 0; i < numFirst; i++) {
bookSeat[i] = new JTextArea("Not booked");
bookSeat[i].setBackground(Color.WHITE);
bookSeat[i].setEditable(false);
p2.add(bookSeat[i]);
add(p2, BorderLayout.CENTER);//Adding the second JPanel to the main JFrame at the position CENTER.
setVisible(true);
}
}//End of createSeat() method.

@Override
public void actionPerformed(ActionEvent e) {//A method Overrode from the ActionListener interface.

if(e.getSource().equals(btn1)) {//First case: The JButton "Create seats" is clicked.

//Calling the createSeat() method; to create an empty seats based on the entered number of seats in the first JTextField.
createSeat();

//This method called on a container once new components are added or old ones removed.
//This call is an instruction to tell the layout manager to reset based on the new component list.
//revalidate() will trigger a call to repaint what the component thinks are 'dirty regions.'
//https://stackoverflow.com/questions/1097366/java-swing-revalidate-vs-repaint
revalidate();
}
else if(e.getSource().equals(btn2)) {//Second case: The JButton "Book" is clicked.

//Storing the values of the second and third JTextField into 2 integer variables.
//With removing the spaces in them if there is any using "trim()".
numSecond = Integer.parseInt(txtAgents.getText().trim());
numThird = Integer.parseInt(txtTime.getText().trim());


//Creating an ExecutorService object with fixed thread pool with maximum number of agents threads.
ExecutorService executor = Executors.newFixedThreadPool(numSecond);

//for-loop for the number of times the ExecutorService (thread pool) should run.
//It will keep creating threads until it reaches the maximum number of seats.
for(int i = 0; i < numFirst; i++) {
int count = i;

//Submitting Runnable task to the executor.
executor.execute(new Runnable() {

@Override
public void run() {//A method Overrode from the Runnable interface.
try {
//Getting the name of the current thread & store it in a String variable.
//Then we will have a long name like: pool-1-thread-n (n is a changing thread number).
//We use split("-"); to split it to 4 parts and we take the 4 part which is in position [3].
name = Thread.currentThread().getName();
agentNumber = name.split("-");


//Setting the new text and background color to the JTextArea array after they get booked.
bookSeat[count].setText("Booked by Agent " + agentNumber[3]);
bookSeat[count].setBackground(Color.RED);

revalidate();

//Generating random number between 0 and the waiting time entered by the user.
//And inserting this value inside the sleep() method. For a waiting time between each thread.
x = ran.nextInt(numThird + 1);
Thread.currentThread().sleep(x);
}
catch (Exception e) {}
}//End of run() method.
});//End of the executor.
}//End of the for-loop.


//Temporary solution for finding the similar elements in the array and return the sum for each
//equal threads. BUT NOT WORKING!!!
z = 0;
for(int i = 0; i < numFirst;i++) {
for(int j = 0; j < numFirst; j++) {
if(bookSeat[i].getName().equals(bookSeat[j].getName())) {
sum[i] = z + 1;
}
}
}


//for-loop for storing the booked seats in a String variable.
output = "";
for(int i = 1; i <= numSecond; i++) {
String allAgents = String.valueOf(i);
output += ("\n" + "Agent " + allAgents + " booked " + sum + " seats.");
}

//Displaying a Message Dialog with the information of each agent's booking.
JOptionPane.showMessageDialog(this,output);


//Shutdown the executor.
executor.shutdown();


//Wait until all tasks are finished.
while(!executor.isTerminated()) {
System.out.println("The booking has finished");
}
}//End of else if condition.
}//End of actionPerformed() method.

public static void main(String [] args) {//Main method.
new Gui(); //Calling the Gui.
}//End of Main method.
}//End of the class.

正如您所见,我尝试使用嵌套 for 循环来检查数组中的元素是否相似并返回它们的总和。但这仍然不起作用!

        z = 0;
for(int i = 0; i < numFirst;i++) {
for(int j = 0; j < numFirst; j++) {
if(bookSeat[i].getName().equals(bookSeat[j].getName())) {
sum[i] = z + 1;
}
}
}

最佳答案

使用 Executor,您将失去对等待它所需的 Thread 实例的直接访问(例如 join())。

首先创建一个线程数组,然后启动它们,然后 join() 它们。例如:

    int numSecond = 3;

Runnable r = new Runnable() {
@Override
public void run()
{
// do your stuff inside thread
}//End of run() method.
};

IntStream.range(1,numSecond + 1).forEach( i -> {
Thread t = new Thread( r, "pool-1-thread-" + i);
t.start();

try
{
t.join();
}
catch ( InterruptedException t1 )
{
System.err.println( "thread interrupted" );
}
});

上面的示例按照您在代码中的预期命名线程:

"pool-1-thread-" + i

如果您只对数字感兴趣,则只需传入

"" + i

使用 CompletableFutures 也可以以一种优雅的方式解决这个问题。

顺便说一句:在线程的 run 方法末尾使用 sleep(x) 绝对没有意义。它不会延迟另一个线程的启动时间。你为什么要这么做?如果你想顺序执行run()中的逻辑,根本不需要创建use线程。

顺便说一句:下次你问问题时,请将你的代码精简到最少,以显示你的问题。无需设置带有按钮、klick 处理程序等的整个 GUI。

BTW3:从线程内部对共享(全局)变量的访问必须同步。

关于java - 如何对java中ExecutorService内部的相似线程求和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58902039/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com