gpt4 book ai didi

java - 在数组中使用多线程

转载 作者:行者123 更新时间:2023-11-30 05:24:05 27 4
gpt4 key购买 nike

我正在尝试执行以下操作: This is what i am trying to do

我想创建一个数组并使用由线程执行的方法。全部集中在一个类“嵌入类”

一种随机找到最大数0的方法,然后将其称为max。一种查找 0 并将其递增 max + 1 的方法。

然后计算所有数组的总和。看图就更清楚了。

这就是我到目前为止所做的,但没有按预期工作

package javaapplication7;


import java.util.*;
import java.util.concurrent.*;

public class JavaApplication7 {

private static Array array = new Array();
public static void main(String[] args) {

ExecutorService executor = Executors.newCachedThreadPool();
Scanner input = new Scanner(System.in);

System.out.println("Enter number");
int num = input.nextInt();

int array[] = new int[num];

for (int i = 0; i < array.length; i++) {
array[i] = 0;
}

for (int i = 0; i < array.length; i++) {
System.out.println("array["+i+"]: "+array[i]);
}

for (int i = 0; i < num; i++) {
executor.execute(new MyThread());
}


executor.shutdown();

while(!executor.isTerminated()){

}

System.out.println("What is balance? ");
}

private static class MyThread implements Runnable{
@Override
public void run(){
array.insert();
}
}

private static class Array{
private int [] array;
private int maximum;

public void setArrayNumbers(){
for (int i = 0; i < array.length; i++) {
array[i] = 0;
}
}
public int getMax(){
return maximum;
}

public synchronized void insert(){
try{
for (int i = 0; i < array.length; i++) {
if(array[i] == 0){
array[i] = array[i] + 1;
}else if(array[i] == 1){
array[i] = array[i] + 1;
}else if(array[i] == 2){
array [i] = array[i] + 1;
}
}
Thread.sleep(100);
}
catch(Exception ex) {
System.out.println(ex);
}
}
}
}

帮助我纠正错误,以便我更好地理解多线程谢谢!

最佳答案

首先,停止扩展Thread。这实际上是Java中处理多线程的一种非常不方便的方式。还有很多更好的东西,比如接口(interface) RunnableCallable

我只是按照练习的编写方式实现了这一点:

import java.util.Arrays;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Fun implements Runnable {

int[] numbers;

public Fun(int[] numbers)
{
this.numbers = numbers;
}

public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Please enter the amount of threads: ");
final int qtyThreads = in.nextInt();

int[] numbers = new int[qtyThreads];

for(int i = 0; i<numbers.length; i++)
{
numbers[i] = 0;
}

ExecutorService exs = Executors.newFixedThreadPool(qtyThreads);

for(int i = 0; i<qtyThreads; i++)
{
exs.submit(new Fun(numbers));
}

// already awaits termination
exs.shutdown();

int sum = 0;

for(int number : numbers)
{
sum += number;
}

System.out.println("ArraySum: "+sum);



}


@Override
public void run() {

int max = -1;
for(int i = 0; i<numbers.length; i++)
{
if(numbers[i] > max)
{
max = numbers[i];
}
}

for(int i = 0; i<numbers.length; i++)
{
if(numbers[i] == 0)
{
numbers[i] = ++max;
break;
}
}

}

}

这里是关于线程安全的部分:

要在这种情况下实现此目的,您必须在每次写入时锁定数组,这样就不会出现线程并发修改的情况。

因此,在 run 方法中,我们在第二个循环之前有一个 this.lock.lock(); ,在第二个循环之后有一个 this.lock.unlock();第二个循环。

锁的类型为 ReentrantLock并传递给Fun的构造函数,因此每个Thread都有相同的锁实例。

lock() 方法实际上会等待,直到锁可用。如果你在这里做错了什么并且没有解锁锁,就会导致死锁情况。

基本上,当涉及到验证总和时,总和的值应始终为 sum(n) = sum(n-1)+n - 您可以通过以下任一操作找到这一点:一些数学的东西,或者因为我的数学从来都不是特别好,所以我只是做了以下事情:

1: 1
2: 3 (+2)
3: 6 (+5)
4: 10 (+9)
5: 15 (+14)

由此得出的结论是,总和始终是前一个总和加上用户输入。然而,这不是进行数学证明的方式。

如果您想检查多线程解决方案是否正常工作,您始终可以编写一个单线程解决方案并比较这些值 - 这比在纸上进行要容易得多,无论如何,您都不会在纸上这样做:

public static int validateWithSingleThread(int n)
{

int[] numbers = new int[n];

for(int itt = 0; itt<n; itt++)
{
int max = -1;
for(int i = 0; i<numbers.length; i++)
{
if(numbers[i] > max)
{
max = numbers[i];
}
}

for(int i = 0; i<numbers.length; i++)
{
if(numbers[i] == 0)
{
numbers[i] = ++max;
}
}
}

int sum = 0;

for(int number : numbers)
{
sum += number;
}


return sum;

}

关于java - 在数组中使用多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59009939/

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