Мне нужно вставить элементы, используя три потока, создав три класса, а именно Task1, Task2 и Task3. В массив должны быть вставлены значения 0,1,2,....299.
Переопределите метод запуска в потоках. Три целых числа i, j и k, представляющие количество элементов, которые каждый поток должен добавить в данный массив.
Первый поток должен добавлять 0 к i-1 внутри массива, второй поток должен добавлять i к i+j-1 внутри массива, а третий поток должен добавлять i+j к 299 внутри массива.
Потоки один и два должны выполняться одновременно, а значения потоков один и два должны быть вставлены внутрь индексов массива от 0 до i+j-1 случайным образом. Третий поток должен запускаться только после выполнения первых двух потоков. полностью.
В этих кодах даны три задания. первая задача и вторая задача начинают выполнять поток одновременно, и после завершения первых двух задач запускается только третья задача. Если эта ситуация исправится, метод test() вернет true.
public static final int[] threadArray = new int[300]; как я добавляю случайное число в этот массив, используя классы Task1 Task2 и Task3.
Вход :
80
130
90
Выход :
Истинный
import java.util.Scanner;
class Task1 extends Thread
{
static int a = 0;
static int beg = 0;
public void run()
{
for(int i=a;i<=beg;i++)
{
Solution.threadArray[i] = i;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Task2 extends Thread
{
static int a = 0;
static int beg = 0;
@Override
public void run()
{
// TODO Auto-generated method stub
for(int i=a;i<=beg;i++)
{
Solution.threadArray[i] = i;
}
}
}
class Task3 extends Thread
{
static int a = 0;
static int beg = 0;
public void run()
{
// TODO Auto-generated method stub
for(int i=a;i<=beg;i++)
{
Solution.threadArray[i] = i;
}
}
}
public class Solution
{
public static final int[] threadArray = new int[300];
public static volatile String i = 0+"";
public boolean test() throws InterruptedException
{
Task1 task1 = new Task1();
Task2 task2 = new Task2();
Task3 task3 = new Task3();
Thread task2Thread = new Thread(task2);
Thread task3Thread = new Thread(task3);
task1.start();
task2Thread.start();
task1.join();
task2Thread.join();
task3Thread.start();
int first = Task1.a+Task2.a;
int containsSecondThread = Task1.a;
String oneAndTwo = "";
String sizeOfTask1 = "";
for(int i=0;i<first;i++)
{
oneAndTwo += threadArray[i]+" ";
}
for(int i=0;i<containsSecondThread;i++)
{
sizeOfTask1 += threadArray[i]+" ";
}
int begOfTask3 = Task3.beg;
String checkingString = "";
for(int i=begOfTask3;i<threadArray.length;i++)
{
checkingString += i + " ";
}
String task3String = "";
for(int j = begOfTask3;j<threadArray.length;j++)
{
task3String += threadArray[j]+" ";
}
if ((!oneAndTwo.contains(begOfTask3+"") && sizeOfTask1.contains(Task2.beg+"")) || task3String.equals(checkingString))
{
return true;
}
return false;
}
public static void main(String[] args) throws InterruptedException
{
Scanner sc= new Scanner(System.in);
Solution solution = new Solution();
int one = sc.nextInt();
Task1.a = one;
Task1.beg = 0;
int two = sc.nextInt();
Task2.a = two;
Task2.beg = one;
int three = sc.nextInt();
Task3.a = three;
Task3.beg = one+two;
System.out.print(solution.test());
}
}
Во-первых, некоторые наблюдения относительно вашего кода: вместо использования статических переменных в классах (т. е. Task1
, Task2
и Task3
), которые расширяют класс Thread
(чтобы понять, почему взгляните на Почему статические переменные считаются злом?) :
static int a = 0;
static int beg = 0;
используйте нестатические конечные поля и инициализируйте их через конструктор:
class Task1 extends Thread
{
private final int begin;
private final int end;
Task1(int begin, int end){
this.begin = begin;
this.end = end;
}
public void run(){
for(int i=begin; i<= end; i++)
....
}
}
соответствующим образом адаптируйте метод main
:
public static void main(String[] args){
...
Task1 task1 = new Task1(begin, end);
}
а затем передать объекты, связанные с задачами, в качестве параметров метода test
:
public boolean test(Task1 task1, Task2 task2, Task3 task3){
...
}
Для объединения строк используйте StringBuilder
:
StringBuilder oneAndTwo = new StringBuilder();
for(int i=0;i<first;i++)
{
oneAndTwo.append(threadArray[i]).append(" ");
}
Это выглядит неправильно:
Task1.a = one;
Task1.beg = 0;
глядя на цикл метода run
из Task1
, это означает, что если Task1.a
не является отрицательным числом, то Task1
не будет выполнять никакой работы.
Чтобы использовать threads
для генерации случайных значений массива:
int[] threadArray = new int[300];
вы можете начать с извлечения метода для генерации этих случайных значений на основе формулы:
r.nextInt(high-low) + low;
эта формула генерирует случайное значение между low
и high
.
Адаптируйте задачи соответственно:
class Task1 extends Thread
{
private final Random random_values = new Random();
private final int low;
private final int high;
...
public int generate_random(){
return r.nextInt(high-low) + low;
}
public void run()
{
for(....)
{
Solution.threadArray[i] = generate_random();
...
}
}
}
Обязательно передайте в потоки информацию о диапазоне генерируемых случайных значений (т. е. параметры low
и high
) и ссылку на массив, который будет заполнен этими случайными значениями (т. е. массив int[] threadArray
) . Также убедитесь, что вы разделили итерации int[] threadArray
между потоками. Следовательно, каждый поток должен генерировать порцию случайных значений. Примером такого распределения может быть:
Thread 1 : 0 to 100;
Thread 2 : 100 to 200;
Thread 3 : 200 to 300;
Вы можете сделать это более надежным и разделить длину массива на количество потоков и соответственно распределить работу между потоками.
Я мог бы предоставить вам полное решение, но я чувствую, что будет лучше, если я дам вам подсказки, чтобы вы могли сделать это самостоятельно.
Обновлено: на основе нового редактирования вашего вопроса:
Вам просто нужно адаптировать классы Task следующим образом:
class Task1 extends Thread {
static int a = 0;
static int beg = 0;
public void run(){
for(int i=beg;i < a;i++)
Solution.threadArray[i] = i;
}
}
class Task2 extends Thread {
static int a = 0;
static int beg = 0;
public void run(){
for(int i=beg; i< beg + a;i++)
Solution.threadArray[i] = i;
}
}
class Task3 extends Thread{
static int a = 0;
static int beg = 0;
public void run(){
for(int i=beg;i< a + beg;i++)
Solution.threadArray[i] = i;
}
}
Предполагается, что Thread1 и Thread2 имеют доступ к общему ресурсу в threadArray[0... Task1.a+Task2+a]. Поэтому мы должны использовать статическую переменную volatile, которую я объявил в классе решения.
class Task1 extends Thread
{
static int a=0,beg=0;
public void run()
{
int k=Task1.beg;
int i1=0;
while(i1<Task1.a)
{
Solution.threadArray[Integer.parseInt(Solution.i)]=k++;
int a1=Integer.parseInt(Solution.i);
a1++;i1++;
Solution.i=a1+"";
try{
Thread.sleep(1);
}
catch(InterruptedException e){}
}
}
}
class Task2 extends Thread
{
static int a=0,beg=0;
public void run()
{
int y=0;
int k=Task2.beg;
while(y<Task2.a)
{
Solution.threadArray[Integer.parseInt(Solution.i)]=k++;
int a1=Integer.parseInt(Solution.i);
a1++;y++;
Solution.i=a1+"";
try{
Thread.sleep(1);
}
catch(InterruptedException e){}
}
}
}
Thread3 работает независимо после завершения первых двух потоков.
class Task3 extends Thread
{
static int beg=0,a=0;
public void run()
{
for(int i=Task3.beg;i<Task3.beg+Task3.a;i++)
{
Solution.threadArray[i]=i;
}
}
}