В традиционной модели синхронной разработки, когда мы вызываем функцию, данные передаются через параметры функции, а окончательный результат вычисления возвращается через возвращаемое значение функции. Однако в режиме многопоточной асинхронной разработки передача и возврат данных сильно отличаются от режима синхронной разработки. Поскольку запуск и завершение потоков непредсказуемы, при передаче и возврате данных данные не могут быть возвращены через параметры функции и операторы возврата, такие как функции. В этой статье представлены несколько методов передачи данных в потоки по вышеуказанным причинам. В следующей статье мы представим методы возврата данных из потоков.
Если вы хотите сначала получить, вы должны сначала отдать. Обычно при использовании потоков требуются некоторые данные инициализации, а затем поток использует эти данные для обработки и возврата результатов. Первое, что нужно сделать в этом процессе, — передать данные в поток.
1. Передача данных через метод конструктора <BR>При создании потока вы должны создать экземпляр класса Thread или его подкласса. Поэтому нам нетрудно подумать о передаче данных в поток через метод-конструктор класса потока перед вызовом метода start. И сохраните входящие данные, используя переменные класса для использования потоком (фактически используемые в методе запуска). Следующий код демонстрирует, как передавать данные через конструктор:
Скопируйте код кода следующим образом:
пакет мифрид;
публичный класс MyThread1 расширяет поток
{
частное имя строки;
общедоступный MyThread1 (имя строки)
{
это.имя = имя;
}
публичный недействительный запуск()
{
System.out.println("привет " + имя);
}
public static void main(String[] args)
{
Поток потока = новый MyThread1("мир");
поток.start();
}
}
Поскольку этот метод передает данные при создании объекта потока, данные уже находятся на месте до запуска потока, поэтому данные не будут переданы после запуска потока. Если вы хотите передать более сложные данные, вы можете использовать структуры данных, такие как коллекции и классы. Хотя для передачи данных безопаснее использовать метод конструктора, это вызовет массу неудобств, если данных будет много для передачи. Поскольку в Java нет параметров по умолчанию, если вы хотите добиться эффектов, аналогичных параметрам по умолчанию, вам придется использовать перегрузку. Это не только делает сам конструктор слишком сложным, но и значительно увеличивает количество конструкторов. Поэтому, чтобы избежать этой ситуации, передавайте данные через методы класса или переменные класса.
2. Передача данных через переменные и методы <BR>Обычно существует две возможности передать данные в объект. Первая возможность — передать данные через метод конструктора при создании объекта, а вторая возможность — определить серию. открытых методов или переменных (также называемых полями). Затем после создания объекта присваивайте значения одно за другим через экземпляры объекта. Следующий код представляет собой модификацию класса MyThread1, использующую метод setName для установки переменной имени:
Скопируйте код кода следующим образом:
пакет мифрид;
публичный класс MyThread2 реализует Runnable
{
частное имя строки;
public void setName (имя строки)
{
это.имя = имя;
}
публичный недействительный запуск()
{
System.out.println("привет " + имя);
}
public static void main(String[] args)
{
MyThread2 myThread = новый MyThread2 ();
myThread.setName("мир");
Поток потока = новый поток (myThread);
поток.start();
}
}
3. Передача данных через функции обратного вызова <BR>Наиболее часто используются два метода передачи данных в потоки, рассмотренные выше. Но оба метода активно передают данные в класс потока в основном методе. Для потоков эти данные принимаются пассивно. Однако в некоторых приложениях необходимо получать данные динамически во время работы потока. Например, в методе run следующего кода генерируются три случайных числа, а затем сумма этих трех случайных чисел вычисляется с помощью метода процесса. класса Work и вернуть результат через значение класса Data. Как видно из этого примера, перед возвратом значения необходимо получить три случайных числа. Другими словами, это значение нельзя передать в класс потока заранее.
Скопируйте код кода следующим образом:
пакет мифрид;
данные класса
{
общедоступное значение int = 0;
}
классная работа
{
публичный недействительный процесс (данные данных, целые числа)
{
for (int n: числа)
{
data.value += n;
}
}
}
публичный класс MyThread3 расширяет поток
{
частная трудовая деятельность;
общедоступный MyThread3 (работа, работа)
{
this.work = работа;
}
публичный недействительный запуск()
{
java.util.Random случайный = новый java.util.Random();
Данные данных = новые данные();
int n1 = random.nextInt(1000);
int n2 = random.nextInt(2000);
int n3 = random.nextInt(3000);
work.process(data, n1, n2, n3 // Используем функцию обратного вызова);
System.out.println(String.valueOf(n1) + "+" + String.valueOf(n2) + "+"
+ String.valueOf(n3) + "=" + data.value);
}
public static void main(String[] args)
{
Поток потока = новый MyThread3 (новая работа());
поток.start();
}
}
Метод процесса в приведенном выше коде называется функцией обратного вызова. По сути, функции обратного вызова — это функции событий. В Windows API функции обратного вызова часто используются для взаимодействия с данными между программой, вызывающей API. Следовательно, процесс вызова функции обратного вызова является исходным процессом инициирования события. В этом примере вызов метода процесса для получения данных эквивалентен запуску события в методе запуска.