Java многопоточной основе (а)

Краткое введение

В контактирующем 多线程раньше в нашей программе может выполнять только один шаг в любое время, вызов 单线程. Все процедуры выполняются последовательно в пути однопоточных программы , разработанной перед вами необходимо выполнить, будет выполняться последним. Преимущества однопоточных также очевиден, более стабильных по отношению к многопоточным, тем более масштабируемые, разработки приложений относительно легко. Однако, поскольку каждый будет ждать мандат , чтобы начать новую задачу завершения, что приводит к снижению эффективности по сравнению с многопоточной, и даже иногда будет появляться приложение явление анабиоза. Использование многопоточности в пользу полнофункционального многопроцессорных. Создавая многопоточный процесс, каждый поток , выполняющийся на процессоре, что позволяет параллельных приложений, так что каждый процессор полностью работоспособны. Многопоточность является очень важным аспектом обучения Java, Java является то , что каждый программист должен освоить базовые навыки. Эта статья о некоторых базовых знаний Java многопоточных суммированы.

Различие между процессами и потоками

процесс

Процесс является 操作系统资源分配основной единицей, то базовая операционная система, является деятельность , которая возникает , когда программа и данные , порядок выполнения на процессоре. Программа в памяти для запуска, который становится процессом. Процесс находится в процессе запуска программы, и с некоторыми отдельными функциями. В сущности, процесс выполнения программы в операционной системе процесса , который динамически генерируется, разрушения динамических, имеет свой жизненный цикл и различные рабочие состояния. В то же время, этот процесс также имеет параллелизм, он может быть выполнен одновременно вместе с другими процессами, в соответствии с независимой, непредсказуемой скорости вперед ( PS:并发性和并行性是不同的概念,并行指的是同一时刻,两个及两个以上的指令在多个处理器上同时执行。而并发指的是同一时刻只有一条指令执行,但是多个进程可以被 CPU 快速交换执行,给我们感觉好像是多个执行在同时执行一样). 

нить

Поток является 任务调度和执行основной единицей, также упоминается как 轻量级进程нить с помощью нити ID, текущий указатель команд (ПК), набор регистров и стек компонентов. Тема не принадлежит к системным ресурсам, это будет только немного необходимых ресурсов во время выполнения, но он может разделить все ресурсы , принадлежащие процессу и нити принадлежат одному и тому же процессу. Поток может принадлежать только к одному процессу, и процесс может иметь несколько потоков, но есть по крайней мере один поток.

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

Создание резьбы путь

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

Способ наследования класса Thread

шаг- определить класс , который наследует от Threadкласса, а затем переопределить класс runметод, этот метод представляет собой нить для выполнения этой задачи

шаг 2 , чтобы создать объект потока создается Threadэкземпляр подкласса класса

шаг 3 создан из двух шагов объекта вызова startметода , чтобы запустить поток

/**
 * @author mghio
 * @date: 2019-12-07
 * @version: 1.0
 * @description: 通过继承 Thread 类的方式创建线程
 * @since JDK 1.8
 */
public class CreateThreadByExtendsThread extends Thread {

  @Override
  public void run() {
    IntStream.rangeClosed(1, 10).forEach(i -> System.out.println(Thread.currentThread().getName() + " " + i));
  }

  public static void main(String[] args) {
    CreateThreadByExtendsThread threadOne = new CreateThreadByExtendsThread();
    CreateThreadByExtendsThread threadTwo = new CreateThreadByExtendsThread();
    CreateThreadByExtendsThread threadThree = new CreateThreadByExtendsThread();

    threadOne.start();
    threadTwo.start();
    threadThree.start();
  }

}
复制代码
Второй способ достижения Runnable интерфейс

шаг- определить класс , который реализует Runnableинтерфейс, а затем реализовать интерфейс runметод, этот метод также означает , что нить для выполнения этой задачи

шаг 2 для создания Runnableэкземпляров интерфейса класса, и использовать его в качестве примера Thraedпараметра конструктора , чтобы создать Threadкласс объекта, объект реального объект потока

шаг 3 вызывающий объект потока startметод , чтобы начать нить

/**
 * @author mghio
 * @date: 2019-12-07
 * @version: 1.0
 * @description: 通过实现 Runnable 接口的方式创建线程
 * @since JDK 1.8
 */
public class CreateThreadByImplementsRunnable implements Runnable {

  @Override
  public void run() {
    IntStream.rangeClosed(1, 10).forEach(i -> System.out.println(Thread.currentThread().getName() + " " + i));
  }

  public static void main(String[] args) {
    CreateThreadByImplementsRunnable target = new CreateThreadByImplementsRunnable();
    new Thread(target, "thread-one").start();
    new Thread(target, "thread-two").start();
    new Thread(target, "thread-three").start();
  }

}
复制代码
Три способа достижения отзывного интерфейса

шаг 1 определить класс , который реализует Callableинтерфейс, а затем реализовать интерфейс callметода, этот метод также указывает на нить , чтобы выполнить поставленную задачу, и возвращает значение

шаг- Создать Callableэкземпляр интерфейса класса, используя FutureTaskкласс , чтобы обернуть Callableобъект, то FutureTaskобъект инкапсулирует Callableобъект callвозвращаемого значения методы

шаг 3 и использовать FutureTaskобъект как Thraedсоздание аргумент конструктора Threadобъекта, и вызвать объект startметод , чтобы начать нить

шаг 4 призыва FutureTaskобъект getметод , чтобы получить возвращаемое значение после окончания выполнения потока

/**
 * @author mghio
 * @date: 2019-12-07
 * @version: 1.0
 * @description: 通过实现 Callable 接口的方式创建线程
 * @since JDK 1.8
 */
public class CreateThreadByImplementsCallable implements Callable<Integer> {

  @Override
  public Integer call() {
    AtomicInteger count = new AtomicInteger();
    IntStream.rangeClosed(0, 10).forEach(i -> {
      System.out.println(Thread.currentThread().getName() + " " + i);
      count.getAndIncrement();
    });

    return count.get();
  }

  public static void main(String[] args) {
    CreateThreadByImplementsCallable target = new CreateThreadByImplementsCallable();
    FutureTask<Integer> futureTask = new FutureTask<>(target);

    IntStream.rangeClosed(0, 10).forEach(i -> {
      System.out.println(Thread.currentThread().getName() + " 的循环变量 i 的值" + i);
      if (i == 8) {
        new Thread(futureTask, "有返回值的线程").start();
      }
    });

    try {
      System.out.println("有返回值线程的返回值:" + futureTask.get());
    } catch (InterruptedException | ExecutionException e) {
      e.printStackTrace();
    }
  }

}
复制代码

Через выше можно видеть, на самом деле, путем реализации Runnableинтерфейса и реализации , Callableчтобы создать интерфейс этих двух потоков в основном таким же образом, использование реализации Runnableи Callableкогда интерфейс режима для создания потока, класс резьбы только реализует интерфейс также может наследовать другие классы ( PS:Java 单继承决定). Таким образом, несколько потоков могут разделять один и тот же targetобъект, поэтому идеально подходит для нескольких потоков для обработки той же ситуации с ресурсом. Другое дело, что, используя наследование Threadпри создании нескольких потоков и т.п., простой в приготовлении, если вам нужен доступ к текущему потоку, вам не нужно использовать Thread.currentThread()метод, используемый непосредственно thisдля получения текущего потока. Если использование этих трех способов создания потока, если вы создаете замкнутую часто потребляются в реальном проекте влияет на производительность системных ресурсов, и вы не можете использовать нить пула потоков , когда поток обратно в бассейн, а затем взять время из пула потоков, так наше развитие проекта в основном используют пул потоков, пул потоков , посмотрите на эти два могут Java пула потоков (а) , Java пул потоков (II) .

Несколько состояние резьбы

Поток представляет собой динамический процесс исполнения, он также имеет процесс к смерти продукцию, в Java, нить полный жизненный цикл включает в себя в общей сложности пяти государств из следующего: Нового состояния (New) При использовании newключевых слов и Threadкласса или подкласс созданных после того, как объект нить, нить вошла 新建状态, то и другие Java объекты, просто память JVM выделяет и инициализирует переменные значения своих членов, он будет оставаться в этом состоянии до вызова объекта startметода.

Состояние готовности (Runnable) Когда объект потока называется startпо методе, поток в состояние готовности. Готовый поток будет помещен в очереди готовой, ожидая планировщик JVM для планирования. Тема состояния готовности в любой момент времени может быть выполнена с помощью планирования процессора.

Рабочее состояние (Запуск) Если готовое состояние выполнение осуществляются с помощью планирования процессора, вы можете выполнить runметод, то поток в состоянии потока. Тема работы наиболее сложным, он может стать 阻塞状态, 就绪状态и 死亡状态. Обратите внимание , что поток становится 运行状态состоянием , прежде всего 就绪状态.

Заблокированные (Blocked) поток блокируется из - за какой - то причине , чтобы отказаться от использования процессора, и временно прекратит работу, если выполняются sleep, suspendи другие методы, после освобождения ресурсов занята, поток от 运行状态входа 阻塞状态. Ожидание окончания времени ожидания или ресурсы , чтобы получить устройство повторного входа 就绪状态. Препятствие можно разделить на следующие три:

  1. Ожидание блокировки в 运行状态поток вызывает waitметод, поток будет ввести等待阻塞状态
  2. Синхронная блокировка , когда поток приобретает synchronizedблокировки синхронизации , поскольку блокировка используется другим потоком сбоя синхронизации, поток будет ввести同步阻塞
  3. Другие заблокирован вызывающей нити sleepили joinпри выдаче запроса ввода / вывода, поток войдет в состояние блокировки. Когда sleepтайм - аут, joinожидая поток завершается или истекает, или обработку ввода / вывода завершается, поток обратно 就绪状态.

состояние смерти (Dead) а из 运行状态за выполнение потока готового runметода, или потому , что происходит другое условие завершения, поток войдет в 死亡状态конец нити жизненного цикла. Тираж более потоков , представленные различными состояниями заключается в следующем:

нить-состояние-Transfer.png

Тема общего метода

Способ по общему источнику нити можно разделить на две категории, одна наследуется от Objectметода класса, следующим образом :

метод описание
общественности окончательный родной недействительным уведомить () Просыпайтесь один поток, ожидающий на мониторе этого объекта так, что он входит就绪状态
общественности окончательный родной недействительный notifyAll () Проснитесь все темы, ожидающие на мониторе этого объекта так, что он входит就绪状态
общественное окончательное недействительным ждать () Пусть текущий поток 等待阻塞状态, пока другой поток не вызывает объект notifyметод или notifyAllметоды, текущий поток просыпается, он выпустит блокировку,
общественности окончательный родной недействительным ждать (длинный тайм-аут) Пусть текущий поток 等待阻塞状态, пока другой поток не вызывает объект notifyметод или notifyAllметоды, текущий поток просыпается
общественности окончательное аннулируются ожидание (длинный тайм-аут, внутр Nanos) Пусть текущий поток 等待阻塞状态, пока другой поток не вызывает объект notifyметоды или notifyAllметод или другой поток прерывает текущий поток, или определенное количество времени превысили фактический текущий поток просыпается

Другим примером является Threadметод определения класса, как показано ниже:

метод описание
общественности статический родной недействительный выход () Приостановка исполняемую в данный момент объект потока, а также выполнять другую нить, то yieldметод не освобождает замок
общественности статической родной недействительным сна (длинный Миллис) Тема для сна (приостановлено) в настоящее время выполняется в течение указанного числа миллисекунд, sleepметод не освобождает замок
общественности окончательный недействительными присоединиться () При вызове других потоков в потоке выполнения программы , joinкогда метод, вызывающий поток будет заблокирован до тех пор , joinпоток выполнения не был завершен
общественного недействительное прерывание () Для того, чтобы прервать эту нить, когда этот метод вызывается, сразу флаг прерывания установлен в поток true
публичный статический логический прерываться () ThreadМетод статического класса, который возвращает логическое значение , указывающее , был ли прерван текущий поток, interruptedметод возвращает флаг прерывания в дополнении к внешней стороне, он также очищает флаг прерывания (собирается флаг прерывания набора false)
общественного логический isInterrupted () ThreadМетод экземпляра класса , который возвращает логическое значение , указывающее , был ли прерван текущий поток, isInterruptedметод просто возвращает флаг прерывания не будет четко обозначен клеммами

приоритет резьбы

Каждый Java поток имеет приоритет, который помогает определить порядок планирования операционной системы потоков. приоритет потока Java , представляет собой целое число, значение которого диапазоны 1(Thread.MIN_PRIORITY )~ 10(Thread.MAX_PRIORITY ). По умолчанию, каждый поток назначается приоритет NORM_PRIORITY(5). Имеет более высокий приоритет потока является более важным для программы, и следует выделять ресурсы процессора ранее понизить приоритет потока, Threadкласс обеспечивает setPriorityи getPriorityметоды для изменения и получить приоритет потока ( Обратите внимание , что: приоритет потока не гарантируется нить порядок исполнения, но и в значительной степени зависит от платформы ).


Справочная статья

рекомендация

отjuejin.im/post/5dec6544e51d4557ed541c92