JavaRush /Java блог /Random UA /Кава-брейк #1. Різниця між методами sleep(), yield() та j...
Yuliia Tunik
42 рівень
Киев

Кава-брейк #1. Різниця між методами sleep(), yield() та join() в класі Thread. Як розділити ArrayList на менші підсписки (SubLists)

Стаття з групи Random UA

Різниця між методами sleep(), yield() та join() в класі Thread

Джерело: Medium Ця публікація пояснює різницю між методами sleep(), yield() і join() в класі Thread, та як наведені вище методи використовуються для призупинення запущеного потоку з певними цілями. Кава-брейк #1. Різниця між методами sleep(), yield() та join() в класі Thread. Як розділити ArrayList на менші підсписки (SubLists) - 1

Використання методів sleep(), yield() та join()

  • sleep(): якщо використовується призупинення певного потоку (thread) на певний проміжок часу, тоді використовується метод sleep().
  • yield(): якщо ви хочете надати іншим потокам такий самий або вищий пріоритет, ніж має поточний запущений потік, тоді використовується yield().
  • join(): якщо якийсь потік залежить від результату іншого потоку, тоді цей метод призупиняє поточний запущений потік і виконується після завершення виконання іншого потоку.

Приклади

  • sleep(): можна використовувати для миготливих лампочок, слайд-шоу тощо.
  • yield(): під час телефонної розмови зі своїм найкращим другом я отримав вхідний дзвінок від своєї дівчини. Я негайно призупинив поточний дзвінок зі своїм другом і продовжив відповідати на дзвінок своєї дівчини.
  • join(): спочатку прочитати базу даних, а потім показати дані на веб-сайті.

Виклик або відновлення виконання

  • sleep(): автоматично викликається після заданого періоду часу, або коли потік переривається.
  • yield(): головний біль планувальника потоків.
  • join(): автоматично викликається після виконання іншого потоку. Також, якщо надається період часу, то після цього періоду часу. Ще один варіант: коли потік переривається.

Додаткові деталі, на які варто звернути увагу:

sleep():


public static native void sleep(long ms) throws InterruptedException;
public static void sleep(long ms,int ns) throws InterruptedException;
  • Два методи, перевантажені параметрами мілісекунд і наносекунд.
  • native метод присутній.
  • Видає виняток InterruptedException.
  • Усі методи статичні.
  • Методи не final.

yield():


public static native void yield();
  • Жоден метод не перевантажений.
  • Один native метод.
  • Немає появи виключень (exception).
  • Метод не final.
  • Статичний метод.

join():


public final void join() throws InterruptedException;
public final synchronized void join(long ms) throws InterruptedException;
public final synchronized void join(long ms,int ns) throws InterruptedException;
  • Три методи, перевантажені без параметрів, ms і ns.
  • Немає native методу.
  • Видає виключення: InterruptedException.
  • Всі вони final методи.
  • Всі не статичні.

Як розділити ArrayList на менші підсписки (SubLists)

Джерело: Asyncq Завдяки цій статті ви дізнаєтесь три різних способи, як можна розділити ArrayList на менші підсписки (SubLists) у мові програмування Java. Кава-брейк #1. Різниця між методами sleep(), yield() та join() в класі Thread. Як розділити ArrayList на менші підсписки (SubLists) - 2List є однією з найбільш використовуваних колекцій в Java. Іноді список (List) може бути надто великим, тому створення підсписку (SubList) та подальша робота з ним виглядає логічним кроком. На жаль, Java не надає помічника для створення N-кількості підсписків із великого списку, але ми завжди можемо використати існуючу функціональність для реалізації або сторонню бібліотеку.

Список вхідних даних (Input List)

Наші вхідні дані — це простий список N чисел:

List<Integer> numbers = IntStream.rangeClosed(1, 11100)
                .boxed().toList();

Варіант 1

  • У цьому варіанті ми відстежуємо початкові та кінцеві змінні та використовуємо метод sublist(), щоб отримати частину списку, а потім додати цю частину до списку результатів.
  • Ми припиняємо нашу ітерацію щоразу, коли наступна частина менша або дорівнює очікуваному batch_size. Це буде остаточний стан частини.
  • Після цього ми додаємо залишки до результату, і готово!

public static void option_1(){
        int batch_size = 1000;
        List<Integer> numbers = IntStream.rangeClosed(1, 11100)
                .boxed().toList();
        List<List<Integer>> results = new ArrayList<>();
        int start = 0;
        while (start+(batch_size) < numbers.size()){
            int end = start+(batch_size);
            System.out.println(end);
            results.add(numbers.subList(start,end));
            start=end;
        }
        results.add(numbers.subList(start, numbers.size()));
        results.forEach(System.out::println);
    }
Вихід: Кава-брейк #1. Різниця між методами sleep(), yield() та join() в класі Thread. Як розділити ArrayList на менші підсписки (SubLists) - 3

Модифікована версія

  • Ми можемо покращити наш код, додавши Math.min(numbers.size(), start+batch_size).
  • Умова Math.min додасть кінець для обох випадків: 1, коли загальна кількість елементів охоплено пакетом, меншим за загальний розмір запису, і залишкові елементи для останнього пакета.

public static void option_2_modified(){
        int batch_size = 1000;
        List<Integer> numbers = IntStream.rangeClosed(1, 11100)
                .boxed().toList();
        int recordIdx = numbers.size();
        List<List<Integer>> results = new ArrayList<>();
        int start = 0;
        while (start < recordIdx){
            results.add(numbers.subList(start, Math.min(numbers.size(), start+batch_size)));
            start += batch_size;
        }
        results.forEach(System.out::println);
 }

Варіант 2

  • У цьому варіанті ми використовуємо Stream API Java для групування елементів.
  • Ми пропонуємо логіку групування на основі розміру частини та атомарного цілого індексу.
  • Якщо розмір частини дорівнює 10, тоді 0 -> 9 елементів будуть згруповані разом, тому що результат поділу буде 0 для всіх цих елементів.

public static void option_2(){
    int batch_size = 1000;
    List<Integer> numbers = IntStream.rangeClosed(1, 11100)
            .boxed().toList();
    AtomicInteger counter = new AtomicInteger();
    Collection<List<Integer>> result = numbers.stream()
            .collect(Collectors.groupingBy(a -> counter.getAndIncrement() / batch_size))
            .values();
    result.forEach(System.out::println);
}

Варіант 3

Ми також можемо використовувати допоміжні методи, щоб спростити своє життя. Якщо ми маємо право використовувати сторонні бібліотеки, такі як Google Guava або Apache Commons, то ми можемо скористатися допоміжними методами, які надаються цими бібліотеками.

Використання Google Guava Library

У Google Guava є службовий клас Lists, який надає допоміжний метод розділення для розділення списків за розміром пакету.

public static void option_3(){
    int batch_size = 1000;
    List<Integer> numbers = IntStream.rangeClosed(1, 11100)
            .boxed().toList();
    List<List<Integer>> partition = Lists.partition(numbers, batch_size);
    partition.forEach(System.out::println);
}

Використання Apache Commons Collection API

Apache Commons Collection API має клас ListUtils, який надає допоміжний метод розділення для розділення списків із розміром пакету.

public static void option_3(){
    int batch_size = 1000;
    List<Integer> numbers = IntStream.rangeClosed(1, 11100)
            .boxed().toList();
    List<List<Integer>> partition = ListUtils.partition(numbers, batch_size);
    partition.forEach(System.out::println);
}

Висновок

У цій статті ми розглянули три варіанти перетворення великого списку (List) на підсписки (SubLists). Ми реалізували власну логіку та додатково розглянули сторонні допоміжні методи, надані бібліотекою Google Guava та Apache Commons Collections.
Коментарі (1)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
dude.from.odessa Рівень 32
5 березня 2024
"yield(): під час телефонної розмови зі своїм найкращим другом я отримав вхідний дзвінок від своєї дівчини. Я негайно призупинив поточний дзвінок зі своїм другом і продовжив відповідати на дзвінок своєї дівчини." Yuliia Tunik, якщо мама дзвонить, то який буде пріоритет у порівнянні з поточним дзвінком від дівчини?)))