Советы

Потоки в Java

Рассмотрим в общих чертах, что такое потоки, для чего и как они работают. Как и чем они используются в Java, и что под этим подразумевается.

Потоки в Java

Процесс — экземпляр программы , которому выделены системные ресурсы (память, процессор и тд.), выполняется в отдельном адресном пространстве недоступное для других процессов, и соответственно не имеет доступ к структурам другого процесса.

Для каждого процесса ОС создает один главный поток (thread ), который является потоком выполняющихся по очереди команд центрального процессора, который способен создавать другие потоки, пользуясь для этого программным интерфейсом операционной системы.

Потоки для фоновых действий по обслуживанию основных потоков в Java это потоки-демоны

Потоки в Java

Получается Thread — “подпрограмма”, которая выполняется параллельно с основной программой. С позволяет одновременно выполнять различные программные задачи.

Интересный для нас класс — java.lang.Thread. В этом классе определены все методы, необходимые для создания потоков, управления их состоянием и синхронизации.

Thread позволяет:

  • Создавать свой дочерний класс на базе класса Thread. Переопределив метод run, вы получите метод, работающий в рамках отдельного потока.
  • Реализовывать в классе интерфейс Runnable и определять метод run, который будет работать как отдельный поток.

Теперь немного о других потоках. Stream — универсальное представление данных, что позволяет различным программам и устройствам получать и передавать информацию.

В отличии от Thread, который вереница или НИТЬ команд, Stream — ПОТОК переносящий информацию от источника к получателю.

Стандартные потоки (Stream) — потоки процесса зарезервированный для выполнения некоторых «стандартных» функций. В Java доступны три стандартных потока, которые всегда открыты .

Стандартный ввод (0) — зарезервирован для чтения команд пользователя или входных данных. При интерактивном запуске программы по умолчанию нацелен на чтение с устройства текстового интерфейса пользователя (клавиатуры). Потоки в Java

В Java реализован, как: System.in. Стандартный поток ввода in определен как статический объект класса InputStream, который содержит только простейшие методы для ввода данных.

Стандартный вывод (1) — зарезервирован для вывода данных, как правило (хотя и не обязательно) текстовых. При интерактивном запуске программы по умолчанию нацелен на запись на устройство отображения (монитор).

При фоновом режиме обычно переназначают этот поток в файл. System.out — связан с консолью.

Стандартный поток вывода out создан на базе класса PrintStream, предназначенного для форматированного вывода данных в виде текстовой строки.

Стандартный вывод ошибок (2) — зарезервирован для вывода диагностических и отладочных сообщений в текстовом виде. Чаще всего цель этого потока совпадает со стандартным выводом, с отличием в том, что отладочные сообщения процесса, вывод которого перенаправлен, всё равно попадут пользователю.

System.err — стандартный поток вывода сообщений об ошибках err так же, как и стандартный поток вывода out, создан на базе класса PrintStream.

Базовые классы для работы с файлами и потоками Stream

Потоки в Java

  • Вернемся к потокам процесса (Thread).
  • Все потоки, созданные процессом, выполняются в адресном пространстве этого процесса и имеют доступ к ресурсам процесса.
  • Однако поток одного процесса не имеет никакого доступа к ресурсам потока другого процесса, так как они работают в разных адресных пространствах.
  • При необходимости организации взаимодействия между процессами или потоками, принадлежащими разным процессам, следует пользоваться системными средствами, специально предназначенными для этого.
  • В случае выполнения нескольких потоков внутри процесса, специально предназначенный для этого планировщик ОС, который следит за очередностью выполнения потоков, распределяя время выполнения по прерываниям системного таймера.

Потоки созданные разными процесса конкурируют за процессорное время. Для управления распределением времени для потоков в Java предусмотрены три значения для приоритетов потоков. Это NORM_PRIORITY, MAX_PRIORITY и MIN_PRIORITY.

По умолчанию вновь поток имеет нормальный приоритет NORM_PRIORITY, потоки с таким приоритетом пользуются процессорным времени на равных правах. MAX_PRIORITY выполняются раньше тех что с нормальным приоритетом, MIN_PRIORITY — после выполнения всех “нормальных” .

Процессы и потоки в многопоточной системе, могут обращаться одновременно к одним и тем же ресурсам, что может привести к неправильной работе приложений.

Стеки (анг. stack, область памяти хранящая хранящая локальные переменные и ссылки на объекты) для параллельных потоков — РАЗЛИЧНЫЕ,
а область кучи (анг. heap, “медленное хранилище” объектов) этих же потоков — ОБЩАЯ, что служит источником дополнительных проблем.

Потоки в Java

Синхронизация- возможность которая есть в Java, позволяющая синхронизировать не только методы, но и целые блоки программы. Объявление их как synchronized разрешает в один момент времени исполнять данный блок только одному потоку.

Помимо “буквальной” синхронизации, можно скоординировать работу потоков “тонкой” блокировкой потоков: блокировка на заданный период времени, временная приостановка и возобновление работы, ожидание извещения (ожидать, продолжить, всем), ожидание завершения потока .

Потоки в Java
Важный момент: во избежания переполнения памяти или даже падения программы необходимо закрывать потоки явным образом.

Были использованы материалы взятые из:

  1. www.wikipedia.org
  2. www.helloworld.ru
  3. www.progwards.ru
  4. www.pixbay.com

ShuRuPin, Базовый курс, октябрь 2020

Что такое многопоточность в Java

Изучите многопоточность в Java: создание потоков, синхронизация и улучшение производительности в нашей статье для новичков!

Многопоточность — это одновременное выполнение нескольких независимых потоков в одном процессе. В Java, это достигается с помощью класса Thread и интерфейса Runnable. Создание многопоточных приложений позволяет улучшить производительность и отзывчивость программы на вычислительно сложные задачи. Давайте разберемся, как работает многопоточность в Java на примерах. ????

Создание потока с использованием класса Thread

Сначала, создаем новый класс, который наследует от класса Thread:

class MyThread extends Thread {
@Override
public void run() {
// Код для выполнения в новом потоке
}
}

Затем, создаем объект MyThread и вызываем метод start(), который запустит новый поток и выполнит метод run():

MyThread myThread = new MyThread();
myThread.start();

Создание потока с использованием интерфейса Runnable

Альтернативный способ создания потока — это реализация интерфейса Runnable:

class MyTask implements Runnable {
@Override
public void run() {
// Код для выполнения в новом потоке
}
}

Теперь, создаем объект Thread, передавая ему объект MyTask, и вызываем метод start():

MyTask myTask = new MyTask();
Thread thread = new Thread(myTask);
thread.start();

Java-разработчик: новая работа через 11 месяцев

Получится, даже если у вас нет опыта в IT

Получить программуПотоки в Java

Синхронизация потоков

В многопоточных приложениях часто возникают проблемы с доступом к общим ресурсам. Для решения этих проблем используется синхронизация потоков с помощью ключевого слова synchronized. Пример синхронизации метода:

class MyClass {
synchronized void synchronizedMethod() {
// Код для синхронизированного доступа к ресурсам
}
}

Или с использованием синхронизированного блока:

class MyClass {
void someMethod() {
// Несинхронизированный код

synchronized (this) {
// Код для синхронизированного доступа к ресурсам
}

// Несинхронизированный код
}
}

Обратите внимание, что синхронизация может приводить к снижению производительности, поэтому используйте ее только там, где это действительно необходимо.

Теперь вы знаете основы многопоточности в Java и сможете использовать их при создании своих приложений. Удачи в изучении! ????

Дополнительные материалы

Если вы хотите углубить свои знания в многопоточности и Java в целом, рекомендуем обратиться к курсам следующей онлайн-школы:

Java-разработчик: новая работа через 11 месяцев

Получится, даже если у вас нет опыта в IT

Получить программуПотоки в Java

Не забудьте практиковаться и экспериментировать с кодом, чтобы лучше понимать, как работает многопоточность в Java. Успехов в обучении! ????‍????????‍????

Class Thread

java.lang.Object

All Implemented Interfaces:
Runnable

Direct Known Subclasses:
ForkJoinWorkerThread
public class Thread
extends Object
implements Runnable
A thread is a thread of execution in a program.

The Java virtual machine allows an application to have multiple threads of execution running concurrently.

Thread defines constructors and a Thread.BuilderPREVIEW to create threads. Starting a thread schedules it to execute its run method.

The newly started thread executes concurrently with the thread that caused it to start.

A thread terminates if either its run method completes normally, or if its run method completes abruptly and the appropriate uncaught exception handler completes normally or abruptly. With no code left to run, the thread has completed execution. The join method can be used to wait for a thread to terminate.

Threads have a unique identifier and a name. The identifier is generated when a Thread is created and cannot be changed. The thread name can be specified when creating a thread or can be changed at a later time.

Threads support ThreadLocal variables. These are variables that are local to a thread, meaning a thread can have a copy of a variable that is set to a value that is independent of the value set by other threads.

Thread also supports InheritableThreadLocal variables that are thread local variables that are inherited at Thread creation time from the parent Thread.

Thread supports a special inheritable thread local for the thread context-class-loader.

Platform threads

Thread supports the creation of platform threads that are typically mapped 1:1 to kernel threads scheduled by the operating system. Platform threads will usually have a large stack and other resources that are maintained by the operating system. Platforms threads are suitable for executing all types of tasks but may be a limited resource.

Platform threads get an automatically generated thread name by default.

Platform threads are designated daemon or non-daemon threads. When the Java virtual machine starts up, there is usually one non-daemon thread (the thread that typically calls the application's main method). The shutdown sequence begins when all started non-daemon threads have terminated. Unstarted non-daemon threads do not prevent the shutdown sequence from beginning.

In addition to the daemon status, platform threads have a thread priority and are members of a thread group.

Virtual threads

Thread also supports the creation of virtual threads. Virtual threads are typically user-mode threads scheduled by the Java runtime rather than the operating system.

Virtual threads will typically require few resources and a single Java virtual machine may support millions of virtual threads. Virtual threads are suitable for executing tasks that spend most of the time blocked, often waiting for I/O operations to complete.

Virtual threads are not intended for long running CPU intensive operations.

Virtual threads typically employ a small set of platform threads used as carrier threads. Locking and I/O operations are examples of operations where a carrier thread may be re-scheduled from one virtual thread to another.

Code executing in a virtual thread is not aware of the underlying carrier thread. The currentThread() method, used to obtain a reference to the current thread, will always return the Thread object for the virtual thread.

Virtual threads do not have a thread name by default. The getName method returns the empty string if a thread name is not set.

Virtual threads are daemon threads and so do not prevent the shutdown sequence from beginning. Virtual threads have a fixed thread priority that cannot be changed.

Thread defines public constructors for creating platform threads and the start method to schedule threads to execute. Thread may be extended for customization and other advanced reasons although most applications should have little need to do this.

Thread defines a Thread.BuilderPREVIEW API for creating and starting both platform and virtual threads. The following are examples that use the builder:

Copy
Runnable runnable = …

// Start a daemon thread to run a task
Thread thread = Thread.ofPlatform().daemon().start(runnable);

// Create an unstarted thread with name «duke», its start() method
// must be invoked to schedule it to execute.
Thread thread = Thread.ofPlatform().name(«duke»).unstarted(runnable);

// A ThreadFactory that creates daemon threads named «worker-0», «worker-1», …
ThreadFactory factory = Thread.ofPlatform().daemon().name(«worker-«, 0).factory();

// Start a virtual thread to run a task
Thread thread = Thread.ofVirtual().start(runnable);

// A ThreadFactory that creates virtual threads
ThreadFactory factory = Thread.ofVirtual().factory();

Inheritance when creating threads

A Thread inherits its initial values of inheritable-thread-local variables (including the context class loader) from the parent thread values at the time that the child Thread is created.

The 5-param constructor can be used to create a thread that does not inherit its initial values from the constructing thread. When using a Thread.Builder, the inheritInheritableThreadLocalsPREVIEW method can be used to select if the initial values are inherited.

Platform threads inherit the daemon status, thread priority, and when not provided (or not selected by a security manager), the thread group.

Creating a platform thread captures the caller context to limit the permissions of the new thread when it executes code that performs a privileged action.

The captured caller context is the new thread's «Inherited AccessControlContext».

Creating a virtual thread does not capture the caller context; virtual threads have no permissions when executing code that performs a privileged action.

Unless otherwise specified, passing a null argument to a constructor or method in this class will cause a NullPointerException to be thrown.

Implementation Note:
In the JDK Reference Implementation, the virtual thread scheduler may be configured with the following system properties:

System properties

System property Description jdk.virtualThreadScheduler.parallelism

jdk.virtualThreadScheduler.maxPoolSize

The number of platform threads available for scheduling virtual threads. It defaults to the number of available processors.
The maximum number of platform threads available to the scheduler. It defaults to 256.

Since:
1.0

    • public static final int MIN_PRIORITY
      The minimum priority that a thread can have.

      See Also:

    • public static final int NORM_PRIORITY
      The default priority that is assigned to a thread.

      See Also:

    • public static final int MAX_PRIORITY
      The maximum priority that a thread can have.

      See Also:

    • Initializes a new platform Thread. This constructor has the same effect as Thread (null, null, gname), where gname is a newly generated name. Automatically generated names are of the form «Thread-«+n, where n is an integer. This constructor is only useful when extending Thread to override the run() method.

      See Also:

      • Inheritance when creating threads
    • public Thread(Runnable task)
      Initializes a new platform Thread. This constructor has the same effect as Thread (null, task, gname), where gname is a newly generated name. Automatically generated names are of the form «Thread-«+n, where n is an integer.

      For a non-null task, invoking this constructor directly is equivalent to:

      Thread.ofPlatform().unstarted(task);

      Parameters:
      task — the object whose run method is invoked when this thread is started. If null, this classes run method does nothing.
      See Also:

      • Inheritance when creating threads
    • public Thread(ThreadGroup group, Runnable task)
      Initializes a new platform Thread. This constructor has the same effect as Thread (group, task, gname), where gname is a newly generated name. Automatically generated names are of the form «Thread-«+n, where n is an integer.

      For a non-null group and task, invoking this constructor directly is equivalent to:

      Thread.ofPlatform().group(group).unstarted(task);

      Parameters:
      group — the thread group. If null and there is a security manager, the group is determined by SecurityManager.getThreadGroup(). If there is not a security manager or
      SecurityManager.getThreadGroup() returns null, the group is set to the current thread's thread group.
      task — the object whose run method is invoked when this thread is started. If null, this thread's run method is invoked.
      Throws:
      SecurityException — if the current thread cannot create a thread in the specified thread group
      See Also:

      • Inheritance when creating threads
    • public Thread(String name)
      Initializes a new platform Thread. This constructor has the same effect as Thread (null, null, name).

      This constructor is only useful when extending Thread to override the run() method.

      Parameters:
      name — the name of the new thread
      See Also:

      • Inheritance when creating threads
    • public Thread(ThreadGroup group, String name)
      Initializes a new platform Thread. This constructor has the same effect as Thread (group, null, name).

      This constructor is only useful when extending Thread to override the run() method.

      Parameters:
      group — the thread group. If null and there is a security manager, the group is determined by SecurityManager.getThreadGroup(). If there is not a security manager or
      SecurityManager.getThreadGroup() returns null, the group is set to the current thread's thread group.
      name — the name of the new thread
      Throws:
      SecurityException — if the current thread cannot create a thread in the specified thread group
      See Also:

      • Inheritance when creating threads
    • public Thread(Runnable task, String name)
      Initializes a new platform Thread. This constructor has the same effect as Thread (null, task, name).

      For a non-null task and name, invoking this constructor directly is equivalent to:

      Thread.ofPlatform().name(name).unstarted(task);

      Parameters:
      task — the object whose run method is invoked when this thread is started. If null, this thread's run method is invoked.
      name — the name of the new thread
      See Also:

      • Inheritance when creating threads
    • public Thread(ThreadGroup group, Runnable task, String name)
      Initializes a new platform Thread so that it has task as its run object, has the specified name as its name, and belongs to the thread group referred to by group.

      If there is a security manager, its checkAccess method is invoked with the ThreadGroup as its argument.

      In addition, its checkPermission method is invoked with the RuntimePermission(«enableContextClassLoaderOverride») permission when invoked directly or indirectly by the constructor of a subclass which overrides the getContextClassLoader or setContextClassLoader methods.

      The priority of the newly created thread is the smaller of priority of the thread creating it and the maximum permitted priority of the thread group. The method setPriority may be used to change the priority to a new value.

      The newly created thread is initially marked as being a daemon thread if and only if the thread creating it is currently marked as a daemon thread. The method setDaemon may be used to change whether or not a thread is a daemon.

      For a non-null group, task, and name, invoking this constructor directly is equivalent to:

      Thread.ofPlatform().group(group).name(name).unstarted(task);

      Parameters:
      group — the thread group. If null and there is a security manager, the group is determined by SecurityManager.getThreadGroup(). If there is not a security manager or
      SecurityManager.getThreadGroup() returns null, the group is set to the current thread's thread group.
      task — the object whose run method is invoked when this thread is started. If null, this thread's run method is invoked.
      name — the name of the new thread
      Throws:
      SecurityException — if the current thread cannot create a thread in the specified thread group or cannot override the context class loader methods.
      See Also:

      • Inheritance when creating threads
    • Initializes a new platform Thread so that it has task as its run object, has the specified name as its name, and belongs to the thread group referred to by group, and has the specified stack size.

      This constructor is identical to Thread(ThreadGroup,Runnable,String) with the exception of the fact that it allows the thread stack size to be specified. The stack size is the approximate number of bytes of address space that the virtual machine is to allocate for this thread's stack. The effect of the stackSize parameter, if any, is highly platform dependent.

      On some platforms, specifying a higher value for the stackSize parameter may allow a thread to achieve greater recursion depth before throwing a StackOverflowError.

      Similarly, specifying a lower value may allow a greater number of threads to exist concurrently without throwing an OutOfMemoryError (or other internal error).

      The details of the relationship between the value of the stackSize parameter and the maximum recursion depth and concurrency level are platform-dependent. On some platforms, the value of the stackSize parameter may have no effect whatsoever.

    • Потоки в Java. Наследуемся от Thread, реализуем интерфейс Runnable

      Этой статьей я начинаю цикл статей по многопоточности и параллелизму в Java. Сегодня познакомимся с Thread и интерфейсом Runnable. Для того, чтобы понимать многопоточность в Java, нужно знать некоторые понятия.

      Процесс в Java

      Процесс представляет собой автономную среду выполнения и может рассматриваться в качестве программы или приложения. Однако сама программа содержит несколько процессов внутри себя. Например, среда выполнения Java работает как единый процесс, который содержит различные классы и программы.

      Thread в Java

      Thread можно назвать легковесным процесс. Он требует меньше ресурсов для создания и существует в процессе, деля с ним ресурсы.

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

      Каждая Java программа работает как минимум с одним потоком — главным потоком. Несмотря на то, что есть очень много других потоков, работающих в фоновом режиме: управление памятью, управление системой, обработка сигналов и т.д. Но с точки зрения нашей программы — главным будет первый поток.

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

      Преимущества потоков

      1. Потоки намного легче процессов, они требуют меньше времени и ресурсов.
      2. Переключение контекста между потоками намного быстрее, чем между процессами.
      3. Намного проще добиться взаимодействия между потоками, чем между процессами.

      Java предоставляет два способа программно создать поток.

      1. Реализация интерфейса java.lang.Runnable.
      2. Расширение класса java.lang.Thread.

      Пример создания Thread. Реализуем интерфейс Runnable

      Для того, чтобы класс был runnable, мы должны реализовать интерфейс java.lang.Runnable и обеспечить реализацию метода public void run(). Чтобы использовать этот класс, как поток, мы должны создать объект Thread, передавая объект runnable класса, а затем вызвать метод start(), чтобы выполнился метод run() в отдельном потоке.

      Вот пример Java класса, реализующего Runnable интерфейс.

      package ua.com.prologistic;

      public class HeavyWorkRunnable implements Runnable {

      @Override
      public void run() {
      System.out.println(«Начинаем обработку в отдельном потоке — » + Thread.currentThread().getName());
      try {
      Thread.sleep(1000);
      // для примера будем выполнять обработку базы данных
      doDBProcessing();
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      System.out.println(«Заканчиваем обработку в отдельном потоке — » + Thread.currentThread().getName());
      }

      // метод псевдообработки базы данных
      private void doDBProcessing() throws InterruptedException {
      Thread.sleep(5000);
      }

      }

      package ua.com.prologistic;public class HeavyWorkRunnable implements Runnable {        System.out.println(«Начинаем обработку в отдельном потоке — » + Thread.currentThread().getName());            // для примера будем выполнять обработку базы данных        } catch (InterruptedException e) {        System.out.println(«Заканчиваем обработку в отдельном потоке — » + Thread.currentThread().getName());    // метод псевдообработки базы данных    private void doDBProcessing() throws InterruptedException {

      Пример создания потока. Наследуем класс Thread

      Мы можем наследовать класс java.lang.Thread для создания собственного класса Thread и переопределить метод run(). Тогда мы можем создать экземпляр этого класса и вызвать метод start() для того, чтобы выполнить метод run().

      Вот простой пример того, как наследоваться от класса Thread:

      package ua.com.prologistic;

      public class MyThread extends Thread {

      public MyThread(String name) {
      super(name);
      }

      @Override
      public void run() {
      System.out.println(«Стартуем наш поток » + Thread.currentThread().getName());
      try {
      Thread.sleep(1000);
      // для примера будем выполнять обработку базы данных
      doDBProcessing();
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      System.out.println(«Заканчиваем наш поток » + Thread.currentThread().getName());
      }
      // метод псевдообработки базы данных
      private void doDBProcessing() throws InterruptedException {
      Thread.sleep(5000);
      }

      }

      package ua.com.prologistic;public class MyThread extends Thread {    public MyThread(String name) {        System.out.println(«Стартуем наш поток » + Thread.currentThread().getName());            // для примера будем выполнять обработку базы данных        } catch (InterruptedException e) {        System.out.println(«Заканчиваем наш поток » + Thread.currentThread().getName());    // метод псевдообработки базы данных    private void doDBProcessing() throws InterruptedException {

      Вот тестовая программа, показывающая наш поток в работе:

      package ua.com.prologistic;

      public class ThreadRunExample {

      public static void main(String[] args){
      Thread t1 = new Thread(new HeavyWorkRunnable(), «t1»);
      Thread t2 = new Thread(new HeavyWorkRunnable(), «t2»);
      System.out.println(«Стартуем runnable потоки»);
      t1.start();
      t2.start();
      System.out.println(«Runnable потоки в работе»);
      Thread t3 = new MyThread(«t3»);
      Thread t4 = new MyThread(«t4»);
      System.out.println(«Стартуем наши кастомные потоки»);
      t3.start();
      t4.start();
      System.out.println(«Кастомные потоки в работе»);

      }
      }

      package ua.com.prologistic;public class ThreadRunExample {    public static void main(String[] args){        Thread t1 = new Thread(new HeavyWorkRunnable(), «t1»);        Thread t2 = new Thread(new HeavyWorkRunnable(), «t2»);        System.out.println(«Стартуем runnable потоки»);        System.out.println(«Runnable потоки в работе»);        Thread t3 = new MyThread(«t3»);        Thread t4 = new MyThread(«t4»);        System.out.println(«Стартуем наши кастомные потоки»);        System.out.println(«Кастомные потоки в работе»);

      Runnable vs Thread

      Если ваш класс предоставляет больше возможностей, чем просто запускаться в виде Thread, то вам лучше реализовать интерфейс Runnable. Если же вам просто нужно запустить в отдельном потоке, то вы можете наследоваться от класса Thread.

      Реализация Runnable является более предпочтительной, поскольку Java поддерживает реализацию нескольких интерфейсов. Если вы наследуете класс Thread, то вы уже не можете наследовать другие классы.

      Интересно знать

      Начиная с Java 8, Runnable представляет собой функциональный интерфейс и мы можем использовать лямбда-выражения для его реализации, вместо анонимного класса. Следите за обновлениями сайта и вы увидите полное руководство по лямбда выражениям в Java!

      Введение в потоки Thread в Java

      Процесс представляет собой экземпляр выполняемой компьютерной программы. Процесс может выполняться процессором или набором процессоров.

      Процесс имеет виртуальное адресное пространство, исполняемый код, открытые дескрипторы системных объектов, контекст безопасности, уникальный идентификатор процесса, переменные среды, класс приоритета, минимальные и максимальные размеры рабочих наборов и, по крайней мере, один поток выполнения.

      Поток — это объект внутри процесса, который может быть запланирован для выполнения. Это базовая единица использования ЦП, состоящая из счетчика программ, стека и набора регистров (и идентификатора потока). Все потоки процесса разделяют его виртуальное адресное пространство и системные ресурсы.

      Нити отличаются от процессов. Поток — это контекст выполнения, тогда как процесс представляет собой совокупность ресурсов, связанных с вычислением. Процесс может иметь один или несколько потоков.

      Реализация потоков и процессов различается между операционными системами, но в большинстве случаев поток является компонентом процесса.

      Java Threads

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

      Поток похож на последовательные программы, то есть один поток имеет начало, конец, последовательность и в любой момент времени во время выполнения потока есть одна точка выполнения. Однако сам поток не является программой. Он не может работать сам по себе, но работает внутри программы.

      Многие потоки могут запускаться одновременно внутри программы. Все Java-программы имеют по крайней мере один поток, известный как основной поток, который создается JVM (виртуальная машина Java) при запуске программы, когда метод main() вызывается с основным потоком.

      Это объект, который имеет свои собственные регистры, стек и сегмент кода, которые могут работать параллельно с другими потоками процесса (процесс представляет собой набор потоков). Каждый поток в Java создается и контролируется классом Java.lang.Thread.

      Программа Java может иметь много потоков, и эти потоки могут выполняться одновременно, либо асинхронно, либо синхронно.

      Существует два способа создания потока в Java:

      1. Расширение класса Thread
      2. Внедрение интерфейса Runnable

      Расширение класса Thread в Java

      Вы можете расширить класс Java.lang.Thread, чтобы создать свой собственный класс потока Java и переопределить метод run(). Затем вы можете создать его объект и вызвать метод start() для выполнения нашего пользовательского метода запуска класса потока Java.

      Пример

      public class TestClass extends Thread{
      public void run(){
      System.out.println(«Print this…..»);
      }
      public static void main(String[] args) {
      TestClass tc = new TestClass();
      tc.start();
      }
      }

      Внедрение интерфейса Runnable в Java

      Вы можете реализовать интерфейс Java.lang.Runnable и обеспечить реализацию в общедоступном методе void run(). Чтобы использовать этот класс как Thread, вам нужно создать объект Thread, передав объект этого класса runnable, а затем вызвать метод start() для выполнения метода run() в отдельном потоке.

      Пример

      public class TestClass implements Runnable{
      public void run(){
      System.out.println(«Print this…..»);
      }
      public static void main(String[] args) {
      TestClass tc = new TestClass();
      Thread tr = new Thread(tc);
      tr.

      start();
      }
      }

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

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

      Источник: http://net-informations.com/Java/cJava/thread.htm

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

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