Java 如何通过两个线程平等地共享列表中的一些数据?
我从其他话题中寻找答案,但我真的不太懂。 我真正想要的是:假设我在一个ArrayList中有一些数据要处理,还有两个线程,或者3个线程?。如何使这些线程平等地获取数据并对其进行处理 e、 g:对于包含10个元素和2个线程的arraylist,每个线程5个元素;对于包含10个元素和3个线程的arraylist,每个线程3个元素,一个线程4个元素 额外问题:我可以明确地说一个特殊的线程必须启动吗 这是我从运行以下代码中得到的: 要在第一个处理器中处理的数据:0 1 2 3 4 5 6 7 8 9 要在第二个处理器中处理的数据: 现有数据: 或者随机的东西 我真正想要的是: -要在第一个处理器中处理的数据:0 2 4 6 8或0 1 2 3 4 -要在第二个处理器中处理的数据:1 3 5 7 9或5 6 7 8 9 -现有数据: 公共类数据{Java 如何通过两个线程平等地共享列表中的一些数据?,java,multithreading,Java,Multithreading,我从其他话题中寻找答案,但我真的不太懂。 我真正想要的是:假设我在一个ArrayList中有一些数据要处理,还有两个线程,或者3个线程?。如何使这些线程平等地获取数据并对其进行处理 e、 g:对于包含10个元素和2个线程的arraylist,每个线程5个元素;对于包含10个元素和3个线程的arraylist,每个线程3个元素,一个线程4个元素 额外问题:我可以明确地说一个特殊的线程必须启动吗 这是我从运行以下代码中得到的: 要在第一个处理器中处理的数据:0 1 2 3 4 5 6 7 8 9 要
private List<Integer> dataIndex = new ArrayList<>();
Data() {
for (int i = 0; i < 10; i++) {
dataIndex.add(i);
}
}
public synchronized Integer extractOneData(){
return dataIndex.remove(0);
}
public List<Integer> getDataIndex() {
return dataIndex;
}
public void printDataIndex() {
System.out.println("Data available:");
for (Integer i : dataIndex) {
System.out.print(i + " ");
}
}
为了方便起见,我将Data和DataProcessor作为内部类,但您可以在本地将它们分开
public class ForcedMultithreading {
public static void main(String[] args) {
ForcedMultithreading f = new ForcedMultithreading();
Data d = f.new Data();
int numberOfThreads = 2;
int perThreadLoad = d.size() / numberOfThreads;
DataProcessor dp1 = f.new DataProcessor(d, "First processor", perThreadLoad);
DataProcessor dp2 = f.new DataProcessor(d, "Second processor", perThreadLoad);
Thread t1 = new Thread(dp1);
Thread t2 = new Thread(dp2);
t1.start();
t2.start();
dp1.displaydataToProcess();
dp2.displaydataToProcess();
d.printDataIndex();
}
class Data {
private List<Integer> dataIndex = new ArrayList<>();
Data() {
for (int i = 0; i < 10; i++) {
dataIndex.add(i);
}
}
public int size() {
return dataIndex.size();
}
public synchronized Integer extractOneData() {
return dataIndex.remove(0);
}
public List<Integer> getDataIndex() {
return dataIndex;
}
public void printDataIndex() {
System.out.println("Data available:");
for (Integer i : dataIndex) {
System.out.print(i + " ");
}
}
}
class DataProcessor implements Runnable {
private Data data;
private String name;
private int perThreadLoad;
private List<Integer> dataToProcess = new ArrayList<>();
DataProcessor(Data data, String name, int perThreadLoad) {
this.data = data;
this.name = name;
this.perThreadLoad = perThreadLoad;
}
@Override
public void run() {
while (perThreadLoad > 0) {
dataToProcess.add(data.extractOneData());
this.perThreadLoad--;
}
}
public void displaydataToProcess() {
System.out.println("Data to be processed in " + name + ":");
for (Integer i : dataToProcess) {
System.out.print(i + " ");
}
System.out.println();
}
}
}
同样在上面的代码中,大小(即10)被2(即两个线程)除以,但你可以详细计算出“大小”的数学公式,而不是“线程数”(例如10/3)的数学公式。为什么不给每个线程你想让它先处理的数据呢?如果是10件事,就给它们5件,然后马上开始。有太多的不同有很多方法可以实现这些。你能解释一下你的外部问题吗?为什么你想平均分配工作,而不是让线程保持相同的工作时间?一个线程可能比另一个线程更快地完成工作有很多原因,例如,如果它与另一个线程共享一个物理内核。每个线程可以计算根据列表的大小,它可以使用的索引。例如,大小10,线程A使用0到大小/2,第二个线程使用大小/2+1到大小,现在您可以使用此方法为未知数量的线程设置更复杂的方式,或者根据大小和分布创建n个线程。结果表明,第一个线程线程正在获取所有数据,而第二个线程只不过是发布一个代码墙,它在所有情况下都不起作用。您应该解释当前解决方案存在哪些问题以及这些问题应该如何解决fixed@RomanVottner我想给OP一个开始的想法。我不想写完整的解决方案。写专业的列表评论中有很多问题,所以我决定写一段代码,至少给OP一个开始的地方。
public static void main(String[] args) {
Data d = new Data();
DataProcessor dp1 = new DataProcessor(d,"First processor");
DataProcessor dp2 = new DataProcessor(d,"Second processor");
Thread t1 = new Thread(dp1);
Thread t2 = new Thread(dp2);
t1.start();
t2.start();
dp1.displaydataToProcess();
dp2.displaydataToProcess();
d.printDataIndex();
}
public class ForcedMultithreading {
public static void main(String[] args) {
ForcedMultithreading f = new ForcedMultithreading();
Data d = f.new Data();
int numberOfThreads = 2;
int perThreadLoad = d.size() / numberOfThreads;
DataProcessor dp1 = f.new DataProcessor(d, "First processor", perThreadLoad);
DataProcessor dp2 = f.new DataProcessor(d, "Second processor", perThreadLoad);
Thread t1 = new Thread(dp1);
Thread t2 = new Thread(dp2);
t1.start();
t2.start();
dp1.displaydataToProcess();
dp2.displaydataToProcess();
d.printDataIndex();
}
class Data {
private List<Integer> dataIndex = new ArrayList<>();
Data() {
for (int i = 0; i < 10; i++) {
dataIndex.add(i);
}
}
public int size() {
return dataIndex.size();
}
public synchronized Integer extractOneData() {
return dataIndex.remove(0);
}
public List<Integer> getDataIndex() {
return dataIndex;
}
public void printDataIndex() {
System.out.println("Data available:");
for (Integer i : dataIndex) {
System.out.print(i + " ");
}
}
}
class DataProcessor implements Runnable {
private Data data;
private String name;
private int perThreadLoad;
private List<Integer> dataToProcess = new ArrayList<>();
DataProcessor(Data data, String name, int perThreadLoad) {
this.data = data;
this.name = name;
this.perThreadLoad = perThreadLoad;
}
@Override
public void run() {
while (perThreadLoad > 0) {
dataToProcess.add(data.extractOneData());
this.perThreadLoad--;
}
}
public void displaydataToProcess() {
System.out.println("Data to be processed in " + name + ":");
for (Integer i : dataToProcess) {
System.out.print(i + " ");
}
System.out.println();
}
}
}