Краткое введение
В контактирующем 多线程
раньше в нашей программе может выполнять только один шаг в любое время, вызов 单线程
. Все процедуры выполняются последовательно в пути однопоточных программы , разработанной перед вами необходимо выполнить, будет выполняться последним. Преимущества однопоточных также очевиден, более стабильных по отношению к многопоточным, тем более масштабируемые, разработки приложений относительно легко. Однако, поскольку каждый будет ждать мандат , чтобы начать новую задачу завершения, что приводит к снижению эффективности по сравнению с многопоточной, и даже иногда будет появляться приложение явление анабиоза. Использование многопоточности в пользу полнофункционального многопроцессорных. Создавая многопоточный процесс, каждый поток , выполняющийся на процессоре, что позволяет параллельных приложений, так что каждый процессор полностью работоспособны. Многопоточность является очень важным аспектом обучения Java, Java является то , что каждый программист должен освоить базовые навыки. Эта статья о некоторых базовых знаний Java многопоточных суммированы.
Различие между процессами и потоками
процесс
Процесс является 操作系统资源分配
основной единицей, то базовая операционная система, является деятельность , которая возникает , когда программа и данные , порядок выполнения на процессоре. Программа в памяти для запуска, который становится процессом. Процесс находится в процессе запуска программы, и с некоторыми отдельными функциями. В сущности, процесс выполнения программы в операционной системе процесса , который динамически генерируется, разрушения динамических, имеет свой жизненный цикл и различные рабочие состояния. В то же время, этот процесс также имеет параллелизм, он может быть выполнен одновременно вместе с другими процессами, в соответствии с независимой, непредсказуемой скорости вперед ( PS:并发性和并行性是不同的概念,并行指的是同一时刻,两个及两个以上的指令在多个处理器上同时执行。而并发指的是同一时刻只有一条指令执行,但是多个进程可以被 CPU 快速交换执行,给我们感觉好像是多个执行在同时执行一样
).
нить
Поток является 任务调度和执行
основной единицей, также упоминается как 轻量级进程
нить с помощью нити ID, текущий указатель команд (ПК), набор регистров и стек компонентов. Тема не принадлежит к системным ресурсам, это будет только немного необходимых ресурсов во время выполнения, но он может разделить все ресурсы , принадлежащие процессу и нити принадлежат одному и тому же процессу. Поток может принадлежать только к одному процессу, и процесс может иметь несколько потоков, но есть по крайней мере один поток.
Разница между этими двумя
- Планирование планирования потоков и назначения в качестве основной единицы процессов в качестве основной единицы собственных ресурсов
- Параллелизм между процессами не только может выполняться одновременно, он может быть выполнен одновременно по нескольким потокам одного и того же процесса
- Имейте ресурсы процесса является самостоятельным структурным подразделением с ресурсами, поток не имеет системных ресурсов, но является частью процесса доступа к ресурсам
- Накладные при создании или процесс аннулирования, потому что система должна быть пересчитана и восстановление ресурсов, что приводит к служебной системе значительно выше , чем стоимость создания или отзывать нити
Создание резьбы путь
В классе 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
и другие методы, после освобождения ресурсов занята, поток от 运行状态
входа 阻塞状态
. Ожидание окончания времени ожидания или ресурсы , чтобы получить устройство повторного входа 就绪状态
. Препятствие можно разделить на следующие три:
- Ожидание блокировки в
运行状态
поток вызываетwait
метод, поток будет ввести等待阻塞状态
- Синхронная блокировка , когда поток приобретает
synchronized
блокировки синхронизации , поскольку блокировка используется другим потоком сбоя синхронизации, поток будет ввести同步阻塞
- Другие заблокирован вызывающей нити
sleep
илиjoin
при выдаче запроса ввода / вывода, поток войдет в состояние блокировки. Когдаsleep
тайм - аут,join
ожидая поток завершается или истекает, или обработку ввода / вывода завершается, поток обратно就绪状态
.
состояние смерти (Dead) а из 运行状态
за выполнение потока готового run
метода, или потому , что происходит другое условие завершения, поток войдет в 死亡状态
конец нити жизненного цикла. Тираж более потоков , представленные различными состояниями заключается в следующем:
Тема общего метода
Способ по общему источнику нити можно разделить на две категории, одна наследуется от 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
методы для изменения и получить приоритет потока ( Обратите внимание , что: приоритет потока не гарантируется нить порядок исполнения, но и в значительной степени зависит от платформы ).
Справочная статья