Перейти к содержимому

Как получить объект из потока java

  • автор:

Получить объект класс из потока в Java

Сервер приложения IBM WebSphere, соответственно, запущен на IBM JVM. Приложение работает в несколько потоков, как WebContainer, так и фоновые процессы. В отдельным потоке получаю все потоки, которые запущены в данной JVM, таким образом:

Set threadSet = Thread.getAllStackTraces().keySet(); for(Thread t: threadSet)

Можно ли каким-то образом получить список всех объектов, например класса java.sql.Connection, или его наследников, и уже от их имени выполнить какой-то запрос к БД. Например, несколько потоков имею свои подключения к БД и мне надо знать какой SQL_ID используется каждым потоком. Возможно это реализовать? Может есть другой способ решения данной задачи?

Как получить данные из потоков обратно в main в java?

Как мне в maine собрать в другой ArrayList res результаты обработки потоков?

  • Вопрос задан более трёх лет назад
  • 4059 просмотров

Комментировать
Решения вопроса 0
Ответы на вопрос 5

targetjump

Y V @targetjump
Ответ написан более трёх лет назад
Комментировать
Нравится 3 Комментировать
Drugs-driven development

Можно использовать Future. Ну или синхронизацию.
Кстати, для многопоточности надо использовать контейнеры, которые специально заточе. . А судя по приведённому коду, тебе нужно почитать литературу по многопоточности в java, а не спрашивать тут такие вещи. Тогда и таких вопросов не будет возникать.

Ответ написан более трёх лет назад
Нравится 2 2 комментария

hudrogen

hudrogen @hudrogen Автор вопроса

Хорошо. Я действительно начал реализовывать алгоритм на досмотрев уроки по многопотчности, думал текущих знаний хватит.

hudrogen

hudrogen @hudrogen Автор вопроса

Для этого существует очередь LinkedBlockingQueue .
Потоки пишут в нее возвращаемые значения, промаркированные id задания.
main читает из нее и восстанавливает массив возвращаемых значений по их id, не опираясь на порядок элементов в очереди, который ничем не гарантирован.

Ответ написан более трёх лет назад
Комментировать
Нравится 2 Комментировать

Используйте коллекции, как уже советовали выше, например очереди или Map’ы. Лучше использовать из пакета java.util.concurrent
Еще можно заюзать новый интерфейс Callable —

Который как раз может возвращать значение, в отличии от Runnable.

Ответ написан более трёх лет назад
Комментировать
Нравится 2 Комментировать
Разработчик

Стартонуть 100 потоков — не лучшая идея. Если у вас конечно не 100 ядерный сервер или кластер.

Создатт ExecutorPool на количество с n + 1 потоков. И запихните туда свой Callable. А потом ждите результата на get()

Вот тут официальный оракловский туториал, как это сделать. Я уверен он поможет разобраться.

Ответ написан более трёх лет назад
Комментировать
Нравится 2 Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

java

  • Java

В каком контексте значение класса String является неизменяемым в отличии от StringBuilder?

  • 1 подписчик
  • вчера
  • 74 просмотра

Как получить объект из потока java

Ряд методов Stream API возвращают подпотоки или объединенные потоки на основе уже имеющихся потоков. Рассмотрим эти методы.

takeWhile

Метод takeWhile() выбирает из потока элементы, пока они соответствуют условию. Если попадается элемент, который не соответствует условию, то метод завершает свою работу. Выбранные элементы возвращаются в виде потока.

import java.util.stream.Stream; public class Program < public static void main(String[] args) < Streamnumbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5); numbers.takeWhile(n -> n < 0) .forEach(n ->System.out.println(n)); > >

В данном случае программа выбирает из потока числа, пока они меньше нуля. Консольный вывод программы:

-3 -2 -1

При этом несмотря на то, что в потоке больше отрицательных чисел, но метод завершает работу, как только обнаружит первое число, которое не соответствует условию. В этом и состоит отличие, например, от метода filter() .

Чтобы в данном случае охватить все элементы, которые меньше нуля, поток следует предварительно отсортировать:

Stream numbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5); numbers.sorted().takeWhile(n -> n < 0) .forEach(n ->System.out.println(n));

Консольный вывод программы:

-5 -4 -3 -2 -1

dropWhile

Метод dropWhile() выполняет обратную задачу — он пропускает элементы потока, которые соответствуют условию до тех пор, пока не встретит элемент, который НЕ соответствует условию:

Stream numbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5); numbers.sorted().dropWhile(n -> n < 0) .forEach(n ->System.out.println(n));

Консольный вывод программы:

0 1 2 3

concat

Статический метод concat() объединяет элементы двух потоков, возвращая объединенный поток:

import java.util.stream.Stream; public class Program < public static void main(String[] args) < Streampeople1 = Stream.of("Tom", "Bob", "Sam"); Stream people2 = Stream.of("Alice", "Kate", "Sam"); Stream.concat(people1, people2).forEach(n -> System.out.println(n)); > >
Tom Bob Sam Alice Kate Sam

distinct

Метод distinct() возвращает только уникальные элементы в виде потока:

Stream people = Stream.of("Tom", "Bob", "Sam", "Tom", "Alice", "Kate", "Sam"); people.distinct().forEach(p -> System.out.println(p));
Tom Bob Sam Alice Kate

Потоки в Java: От рождения до смерти. Введение в многопоточность

Всем привет! В этой статье я бы хотел погрузить в мир жизненного цикла потоков начинающих программистов на Java, заранее извиняюсь за злоупотребление слова «поток» в этой статье, но я надеюсь так будет даже лучше для понимания. Поехали!

Жизненный цикл потока — основная концепция Java, которую мы подробно рассмотрим в этой статье. Мы будем использовать краткую иллюстрированную диаграмму и фрагменты практического кода, чтобы более глубоко понять состояния потока во время его выполнения. Эта статья о создании потока — отличное начало для понимания потоков в Java.

Многопоточность в Java

Многопоточность в языке Java определяется основной концепцией потока. Потоки проходят через различные состояния в течение своего жизненного цикла:

Состояния потока в Java

Жизненный цикл потока

В Java класс java.lang.Thread является фундаментальным компонентом, который позволяет выполнять параллельное программирование. Этот класс предоставляет множество функций для управления выполнением нескольких потоков в программе.

Класс java.lang.Thread содержит перечисление статических состояний, в которых может находиться поток. Эти состояния играют решающую роль в понимании жизненного цикла потока.

Первое состояние — «NEW «. Это состояние представляет собой недавно созданный поток, который еще не начал свое выполнение. В этом состоянии поток готов к планированию операционной системой, но ему не назначено никакого процессорного времени.

Следующее состояние — «RUNNABLE«. Поток в этом состоянии либо запущен, либо готов к выполнению. Однако он может ожидать выделения ресурсов, таких как процессорное время или доступ к общему ресурсу. Как только необходимые ресурсы будут доступны, поток может продолжить свое выполнение.

Другое состояние «BLOCKED «. В этом состоянии поток ожидает получения блокировки монитора(monitor lock), которая необходима для ввода или повторного ввода синхронизированного блока или метода. Поток остается в этом состоянии до тех пор, пока monitor lock не станет доступен.

Ещё одно состояние — «WAITING«. Когда поток находится в этом состоянии, он ожидает, пока какой-либо другой поток выполнит определенное действие без каких-либо временных ограничений. Это может произойти, например, когда один поток ожидает сигнала от другого для продолжения своего выполнения.

Понимая различные состояния потока, разработчики могут эффективно управлять выполнением своих многопоточных приложений. Это позволяет им оптимизировать использование ресурсов и эффективно обрабатывать синхронизацию, обеспечивая бесперебойную и результативную работу своих программ.
Чтобы полностью понять различные состояния потока, важно глубже вникнуть в каждое из них. Давайте начнем с состояния «TIMED_WAITING», он похож на «WAITING», но есть некоторые отличия. Это состояние возникает, когда один поток ожидает от другого выполнения определенного действия, но только в течение определенного периода времени.

«TERMINATED» — состояние, когда поток завершил свое выполнение. Это означает, что он завершил назначенную ему задачу и больше не активен. Важно отметить, что как только поток достигает этого состояния, его нельзя перезапустить или возобновить работу.

Теперь, когда мы обсудили эти состояния более подробно, становится ясно, что понимание жизненного цикла потока имеет решающее значение в программировании. Зная, как потоки переходят между этими состояниями, разработчики могут эффективно управлять выполнением своих программ.

Перейдём к примерам

NEW — это состояние, когда поток был создан, но еще не запущен. В этом состоянии поток ожидает своего запуска с помощью метода start().

Runnable runnable = new NewState(); Thread t = new Thread(runnable); System.out.println(t.getState());

В данном случае метод t.getState() в консоль выведет «NEW«

В многопоточной среде планировщик потоков(Thread-Scheduler) (который является частью JVM) выделяет фиксированное количество времени для каждого потока. Таким образом, он выполняется в течение определенного периода времени, затем передает управление другим выполняемым потокам.

Когда мы создаем новый поток и вызываем для него метод start(), он переходит из состояния NEW в состояние RUNNABLE. Потоки в этом состоянии либо запущены, либо готовы к запуску, но они ожидают выделения ресурсов системой.

Например, давайте добавим метод t.start() в наш предыдущий код и попытаемся получить доступ к его текущему состоянию:

Runnable runnable = new NewState(); Thread t = new Thread(runnable); t.start(); System.out.println(t.getState());

Теперь метод t.getState() вероятнее всего в консоль выведет «RUNNABLE«.
Почему вероятнее всего? Дело в том, что когда наш элемент управления достигнет t.getState(), мы не всегда можем быть уверены, что он будет находиться в состоянии RUNNABLE. Это связано с тем, что в некоторых случаях элемент может быть немедленно запланирован планировщиком потоков (Thread-Scheduler) и завершить своё выполнение. Именно в таких ситуациях возможны другие результаты.

Как мы уже выяснили, поток переходит в состояние Blocked, когда ожидает блокировки монитора(monitor lock) и пытается получить доступ к разделу кода, который заблокирован каким-либо другим потоком.

Давайте попробуем воспроизвести это состояние:

public class BlockedState < public static void main(String[] args) throws InterruptedException < Thread t1 = new Thread(new DemoBlockedRunnable()); Thread t2 = new Thread(new DemoBlockedRunnable()); t1.start(); t2.start(); Thread.sleep(1000); System.out.println(t2.getState()); System.exit(0); >> class DemoBlockedRunnable implements Runnable < @Override public void run() < commonResource(); >public static synchronized void commonResource() < while(true) < >> >
  1. Мы создали два разных потока – t1 и t2
  2. t1 запускается и вводит синхронизированный метод commonResource(); это означает, что только один поток может получить к нему доступ; все остальные последующие потоки, которые попытаются получить доступ к этому методу, будут заблокированы от дальнейшего выполнения до тех пор, пока текущий не завершит обработку.
  3. Когда t1 входит в этот метод, он сохраняется в бесконечном цикле while; Это сделано для имитации интенсивной обработки, чтобы все остальные потоки не могли войти в этот метод.
  4. Теперь, когда мы запускаем t2, он пытается ввести метод commonResource(), к которому уже обращается t1, таким образом, t2 будет сохранен в состоянии BLOCKED.

Поток находится в состоянии WAITING, когда он ожидает, пока какой-либо другой поток выполнит определенное действие. Согласно JavaDocs, любой поток может войти в это состояние, вызвав любой из этих трех методов:

1.object.wait()

2.thread.join()

3.LockSupport.park()

Обратите внимание, что в wait() и join() – мы не определяем какой-либо период ожидания, поскольку этот сценарий рассматривается в следующем разделе.

А пока давайте попробуем воспроизвести это состояние:

public class WaitingState implements Runnable < public static Thread t1; public static void main(String[] args) < t1 = new Thread(new WaitingState()); t1.start(); >public void run() < Thread t2 = new Thread(new DemoWaitingStateRunnable()); t2.start(); try < t2.join(); >catch (InterruptedException e) < Thread.currentThread().interrupt(); e.printStackTrace(); >> > class DemoWaitingStateRunnable implements Runnable < public void run() < try < Thread.sleep(1000); >catch (InterruptedException e) < Thread.currentThread().interrupt(); e.printStackTrace(); >System.out.println(WaitingState.t1.getState()); > >
  1. Мы создали и запустили t1
  2. t1 создает t2 и запускает его
  3. Пока продолжается работа t2, мы вызываем t2.join(), это переводит t1 в состояние ожидания(WAITING), пока t2 не завершит выполнение.
  4. Поскольку t1 ожидает завершения t2, мы вызываем t1.getState() из t2 и получаем результат «WAITING«

Поток находится в состоянии TIMED_WAITING, когда он ожидает, пока другой поток выполнит определенное действие в течение заданного промежутка времени.

Согласно JavaDocs, существует пять способов перевести поток в состояние TIMED_WAITING:

Давайте попробуем воспроизвести это состояние:

public class TimedWaitingState < public static void main(String[] args) throws InterruptedException < DemoTimeWaitingRunnable runnable= new DemoTimeWaitingRunnable(); Thread t1 = new Thread(runnable); t1.start(); Thread.sleep(1000); System.out.println(t1.getState()); >> class DemoTimeWaitingRunnable implements Runnable < @Override public void run() < try < Thread.sleep(5000); >catch (InterruptedException e) < Thread.currentThread().interrupt(); e.printStackTrace(); >> >

Здесь мы создали и запустили поток t1, который переводится в спящее состояние с периодом ожидания 5 секунд; результатом будет «TIMED_WAITING»

TERMINATED — это состояние мертвого потока. Поток находится в состоянии TERMINATED, когда он либо завершил выполнение, либо был как-то был прерван.

Попробуем вызвать это состояние:

public class TerminatedState implements Runnable < public static void main(String[] args) throws InterruptedException < Thread t1 = new Thread(new TerminatedState()); t1.start(); Thread.sleep(1000); System.out.println(t1.getState()); >@Override public void run() < >>

Здесь, мы запустили поток t1, но метод Thread.sleep(1000) дает время, для завершения t1, вследствие чего, эта программа выдает нам в результате «TERMINATED».

Вывод

В этой статье мы узнали о жизненном цикле потока в Java. Мы рассмотрели все шесть состояний, определенных Thread и воспроизвели их с помощью кратких примеров.

Скорее всего фрагменты кода будут выдавать одинаковые выходные данные почти на каждой машине, в некоторых случаях мы можем получить разные выходные данные, так как точное поведение планировщика потоков определить невозможно. Если вам понравилась статья, можете перейти к нам в телеграмм канал и узнать больше полезной информации https://t.me/+bce4rYcDKvMxN2Yy. Желаю удачи в дальнейшем обучении!

  • java
  • потоки
  • многопоточность
  • многопоточное программирование
  • Программирование
  • Java
  • Параллельное программирование

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *