Java — основы многопоточности

Java задняя часть Операционная система API

основная концепция

обработать

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

Принцип компьютерного параллелизма: разделение времени ЦП, альтернативное выполнение, макропараллельный, микропоследовательный. Точно так же меньшая единица планирования задач, разделенная на основе процесса, представляет собой поток.То, что мы называем многопоточностью, заключается в том, что процесс имеет несколько потоков одновременно.

нить

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

состав нитей

Чтобы иметь поток, есть некоторые обязательные части, в основном: квант времени процессора, пространство для хранения данных, код.

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

Создание и запуск потока
Есть два способа традиционного создания потока
  1. Наследовать класс Thread и переопределить метод запуска

  2. Реализуйте интерфейс Runnable и переопределите метод запуска.

Runnable — это не объект потока, а объект задачи. Итак, какова связь между Runnable и Thread?

Изучив API, мы обнаружили, что помимо использования конструктора Thread без параметров, существует параметризованный конструктор, создающий поток: Thread(Runnable target), через который будет выделен новый объект Thread.

Параметр является целевым свойством типа Runnable.

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

JDK1.5

Пул потоков

ExecutorService (интерфейс пула потоков)

//通过工具类中的方法能够新建一个线程池,用ExecutorService接受
ExecutorService es = Executors.newFixedThreadPool(2);

Вызываемый объект

Аналогичен Runnable (интерфейс с описанием задач).

//创建一个Callable的实现类
Callable<Integer> task1 = new Callable<Integer>(){
  public Integer call() throws Exception{
    int result = 0;
    for(int i=2;i<=100;i+=2){
      result += i;
      Thread.sleep;
    }
      return result;
  }
  
}

//用Future对象接收fask1的返回值  将任务提交给线程池
Future<Integer> f = es.submit(task1);
//通过get方法获取Future中的值 在这个时候主线程主动的调取get  如果分支线程还没有结束,主线程会在这里阻塞
int result = f1.get();
//关闭线程池
es.shutdown();

Из вышеприведенного кода мы можем увидеть много отличий.Во-первых, в объекте Callable могут быть выброшены исключения, а во-вторых, есть возвращаемое значение.На этом основании возникает новая проблема.объект? Решение, также данное в JDK1.5, является объектом Future.

начать нить

Здесь нужно понимать, что два вышеуказанных метода не позволят нам получить настоящий поток, а только объект потока, и только запустив поток, мы сможем получить настоящий поток.

Поток можно запустить, выполнив метод start(), но запуск потока не выполняется немедленно.Успешно запущенные потоки находятся в состоянии готовности, когда выполнение должно дождаться получения кванта времени.

Классификация потоков

Пользовательские потоки и потоки демона.

Поток демона: Поток демона будет продолжать работать до тех пор, пока не закончатся все другие потоки, не являющиеся демонами, и он не завершится. Типичный поток демона - это поток сборки мусора, который сосуществует и умирает вместе с виртуальной машиной. Он не завершится, пока виртуальная машина не будет закрыта, когда в виртуальной машине нет потоков. Проще говоря, виртуальная машина существует, она существует. там и виртуальная машина сдохнет.

состояние потока

线程的状态

Как мы уже упоминали выше, поток не будет выполняться сразу после запуска, а находится в состоянии готовности (Ready).Состояние готовности - это разновидность состояния потока. Поток в таком состоянии означает, что все готово и нужно подождать для системы Выделите квант времени. Почему бы не запустить его немедленно, потому что только один поток может заставить квант времени выполняться одновременно. Когда новый поток запускается, запущенный им поток (основной поток) выполняется. Только когда основной поток заканчивается, он имеет возможность получить отрезок времени.

**Состояние потока: **начальное состояние (Новый), состояние готовности (Готово), состояние выполнения (Выполняется) (специальное примечание: в определении грамматики состояние готовности и состояние выполнения являются одним состоянием Выполняется) , состояние ожидания (Ожидание) ), завершено

RUNNABLE), состояние ожидания (Waitering), состояние завершения (Terminated)

Исходное состояние (Новое)

Создается объект потока, который является начальным состоянием.В настоящее время объект потока является обычным объектом, а не потоком.

Runable

**Состояние готовности (Ready): **После выполнения метода запуска он переходит в состояние готовности и ожидает выделения временного интервала.

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

Состояние ожидания (ожидание)

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

Бессрочное ожидание немного отличается. Бессрочное ожидание не означает вечное ожидание, а означает, что нет ограничения по времени, оно может ждать одну секунду или много секунд. Причины входа в ожидание также разные, это может быть из-за того, что истекает квант времени ЦП, это может быть из-за трудоемкой операции (база данных), или активно вызывается метод соединения.

Разница между ожиданием и сном

wait sleep
Метод wait() — это метод класса Object. sleep() — это статический (статический) метод класса Thread.
Когда wait() спит, снять блокировку объекта Когда sleep() спит, сохраните блокировку объекта и все еще удерживайте блокировку
Обычно используется для межпоточной связи Часто используется для приостановки выполнения
wait и notify/notifyAll связаны друг с другом и должны вызываться в блоке синхронизации.
Заблокированное состояние (заблокировано)

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

разница между ожиданием и блокировкой

ждать блокировать
Объект блокировки был получен, или нет ситуации, в которой объект блокировки не может быть получен и не может быть выполнен. Ожидание получения объекта блокировки
жду когда проснутся Ожидание получения объекта блокировки
Завершенный поток (Завершено)

Завершенный поток будет находиться в этом состоянии.

Суммировать

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