Ключевое слово синхронизировано
Синхронизированный ключ может изменять функции и операторы в функциях. Будь то добавлено в методы или объекты, заблокирован, который он приобретает, является объектом, а не рассматривает кусок кода или функции как блокировку.
1. Когда два одновременные потоки получают доступ к синхронизированному (это) синхронизированному кодовому блоку в одном и том же объекте, только один поток может быть выполнен в течение определенного периода времени, а другой поток может выполнять этот код только после того, как текущий поток завершит выполнение.
2. Когда поток обращается к синхронизированному (этому) синхронизированному кодовому блоку в объекте, другие потоки могут по-прежнему получить доступ к другим несинхронизированным (это) блокам кода в этом объекте.
3. Здесь следует отметить, что, когда поток обращается к синхронизированному (этому) кодовому блоку объекта, другие потоки будут заблокированы от доступа к другим синхронизированным (это) синхронизированным кодовым блокам в этом объекте.
4. Выше выше также применимо к другим блокам кода синхронизации, то есть, когда поток обращается к синхронизированному (это) блоке кода синхронизации объекта, поток получает блокировку объекта объекта. Кроме того, каждый объект (то есть экземпляр класса) соответствует блокировке. Он принадлежит, заблокирован. Этот механизм гарантирует, что в то же время, для каждого объекта, не более одной из всех функций членов, объявленных синхронизированными, находится в исполняемом состоянии (потому что в большинстве случаев один поток может получить блокировку объекта), что избегает доступа к переменным члена класса, конфликтую Полем
Недостатки синхронизированного метода:
Поскольку синхронизированный блокирует объект, который вызывает этот метод синхронизации, то есть, когда поток P1 выполняет этот метод в разных потоках, они будут образовывать взаимные исключения, тем самым достигая влияния синхронизации. Но здесь следует отметить, что другой объект класса, который имеет этот объект, может произвольно вызвать этот метод с помощью синхронизированного ключевого слова добавлено. Суть метода синхронизации состоит в том, чтобы применить синхронизированные на ссылке объекта. Этот случай. Мы подробно объясним эту ситуацию ниже:
Во -первых, давайте представим два заблокированных объекта с синхронизированным ключевым словом: объект и класс - Синхронизированный может добавить блокировки объекта или блокировки класса в ресурсы. Из этого класса другие объекты этого класса все еще могут использовать синхронизированный метод, который заблокировал предыдущий объект.
Один из основных вопросов, которые мы обсуждаем здесь: «Будет ли один и тот же класс и разные экземпляры называть один и тот же метод, будет ли проблема синхронизации?»
Проблема синхронизации связана только с ресурсом, и это зависит от того, является ли ресурс статичным. Для тех же статических данных ваша функция принадлежит к разным потокам, чтобы прочитать и написать их одновременно, а ЦП не будет генерировать ошибки. Вы, какая синхронизация необходима. Даже если у вас есть два разных кода, работающие в двух разных ядрах процессора, и одновременно написали адрес памяти, механизм кэша сначала заблокирует один в L2. Затем обновите и поделитесь им с другим ядром, и не будет никаких ошибок, в противном случае Intel или AMD будут напрасными.
Следовательно, до тех пор, пока у вас нет такого же ресурса или переменной, что и два кода, не будет никаких несоответствий данных. Более того, призывы к разным объектам одного и того же класса имеют совершенно разные стеки, и они совершенно не имеют значения.
Здесь мы используем пример, чтобы проиллюстрировать процесс продажи билетов, где наши общие ресурсы являются оставшимся количеством билетов.
Пакет com.test; Общедоступный поток Extends Extends реализует {private static int num = 1; void sell (string name) {if (num> 0) {System. (Завершено примерно за 5 секунд). ; («Система: текущее количество голосов:" + num); args []) {try {newsafetest ("Продавец билетов li xx") .start (); {e.printstacktrace (); Запустите приведенный выше код, и вывод, который мы получаем:
Проводник билета LI XX: Количество тестовых билетов превышает 0 проводника билета LI XX: платеж собирается (завершается примерно за 5 секунд). Полем Полем Продавец билетов King X: количество тестовых билетов превышает 0 продавца билетов King X: платеж собирается (завершается примерно через 5 секунд). Полем Полем Продавец билетов LI XX: Печата счета, Система завершения продаж билетов: Текущее количество голосов: 0 Продавец билетов Ван X: Печать счета, Система завершения продаж билетов: Текущее количество голосов: -1 Предупреждение: количество голосов ниже, чем 0, появляются отрицательные числа
Основываясь на результатах вывода, мы можем обнаружить, что оставшиеся голоса составляют -1, и возникает проблема с ошибкой синхронизации. Причина этого заключается в том, что двухэтапные объекты экземпляра, которые мы создали, изменили общий статический ресурс static int num = 1 одновременно. Затем мы удаляем статический модификатор в поле в приведенном выше коде, а затем запускаем программу, чтобы получить:
Проводник билета LI XX: Количество тестовых билетов превышает 0 проводника билета LI XX: платеж собирается (завершается примерно за 5 секунд). Полем Полем Продавец билетов King X: количество тестовых билетов превышает 0 продавца билетов King X: платеж собирается (завершается примерно через 5 секунд). Полем Полем Продавец билетов LI XX: распечатайте счет, Система завершения продаж билетов: Текущее количество билетов: 0 Продавец билетов Ван X: Печать счет, система завершения продаж билетов: Текущее количество билетов: 0
После изменения степени программа работает без каких -либо проблем. Но это противоречит нашим ожиданиям, что несколько потоков могут обрабатывать общие ресурсы одновременно (после статического изменения от общих ресурсов на переменные члена, принадлежащие каждым экземпляру), что, очевидно, не то, что мы хотим.
В двух вышеупомянутых двух кодах главное, что нужно принять, - это заблокировать объект. По той причине, что я упоминал ранее, когда два разных экземпляра класса изменяют один и тот же общий ресурс, ЦП не по умолчанию будет по умолчанию в логику программы. Поэтому нам нужно изменить объем блокировки. в то же время.
Пакет com.test; Общедоступный поток Extends Extends реализует {private static int num = 1; static void sell (string name) {if (num> 0) {System. Сбор платежей (около 5 секунд завершена). (); .println ("Система: текущий счет:" + num); String args []) {try {new Treadsafetest ("Продавец билетов Li XX") .Start (); ) {e.printstacktrace (); Сделайте программу, как указано выше, чтобы получить результат запуска:
Проводник билета LI XX: Количество тестовых билетов превышает 0 проводника билета LI XX: платеж собирается (завершается примерно за 5 секунд). Полем Полем Продавец билетов LI XX: распечатать билет, Система завершения продаж билетов: Текущее количество билетов: 0 Продавец билетов Wang X: Без билетов, остановка продажи билетов
Статический модификатор добавляется в метод Sell (), так что объект блокировки становится классом. Это получит желаемые результаты, как и ожидалось.
Суммировать:
1. Существует два использования синхронизированных ключевых слов: синхронизированный метод и синхронизированный блок.
2. В Java это не только экземпляр класса, но и каждый класс также может соответствовать замку.
1. Синхронизированное ключевое слово не может быть унаследовано. Хотя синхронизированный может использоваться для определения методов, синхронизированный не принадлежит к части определения метода, поэтому синхронизированное ключевое слово не может быть унаследовано. Если метод в родительском классе использует синхронизированное ключевое слово, а подкласс также переопределяет этот метод, по умолчанию этот метод в подклассе не синхронизирован, и его необходимо отображать, чтобы добавить метод в подкласс. Полем Конечно, вы также можете назвать соответствующие методы в родительском классе в подклассе. быть синхронизированным. нравиться,
Добавьте синхронизированный ключевой слов в подкласс:
Класс Parent {public Synchronized void method () {}} класс Child Extens Parent {public Synchronized void Method () {}} Вызовите метод родительского класса:
Class Parent {public Synchronized void Method () {}} Class Child Extens Parent {public void Method () {super.method (); 2. Синхронизированное ключевое слово нельзя использовать при определении метода интерфейса.
3. Конструктор не может использовать синхронизированное ключевое слово, но синхронизированный блок может использоваться для синхронизации.
4. Синхронизированное положение может быть размещено свободно, но не может быть помещено за возвратный тип метода.
5. Синхронизированное ключевое слово не может быть использовано для синхронизации переменных, таких как неверный код следующего кода:
общественный синхронизированный int n = 0;
6. Хотя использование синхронизированного ключевого слова является самым безопасным методом синхронизации, если он используется в больших количествах, оно также вызовет ненужное потребление ресурсов и потери производительности. На первый взгляд, синхронизированные блокировки метод, но на самом деле он блокирует класс. выполнен. Статические методы аналогичны нестатическим методам. Однако статические методы и нестатические методы не будут влиять друг на друга, см. Следующий код:
Общественный класс Mythread1 Extends {public String Methodname; ");} public synchronized void method2 () {method (" Нестатический метод2 Method ");} public static synchronized void method3 () {method (" Статический метод3 ");} public static synchronized void method4 () {метод ("Статический метод4 Метод"); ) Throws exection {mythread1 mythread1 = new mythread1 (); ); Результат работы:
Нестатический метод1 Метод статический метод 3 Метод
Из приведенных выше результатов мы видим, что Method2 и Method4 не будут работать до тех пор, пока не будут завершены метод1 и метод3. Поэтому мы можем сделать вывод о том, что если мы используем синхронизированный для определения нестатических методов в классе, это повлияет на все синхронизированные не статические методы в этом классе; В этом классе статический метод определяется синхронизированным. Это немного похоже на блокировку таблицы в таблице данных. Следовательно, тяжелое использование этого метода синхронизации значительно снизит производительность программы.
Советы по более безопасному доступу к общим ресурсам:
1. Определите переменную экземпляра Private + ITS METHET, вместо того, чтобы определить переменную экземпляра общественного/защищенного. Если переменная определяется как публичная, объект может напрямую получить его обойти контроль метода синхронизации во внешнем мире и изменить его. Это также одна из стандартных реализаций Javabean.
2. Если переменная экземпляра является объектом, таким как массив или массив, то приведенный выше метод все еще небезопасен, потому что, когда внешний мир получает ссылку на объект экземпляра через метод получения и указывает на другой объект, тогда Частная переменная также изменилась, разве это не очень опасно? В настоящее время вам нужно добавить синхронизированный, чтобы получить метод и вернуть только клон () этого частного объекта. Таким образом, то, что получает вызывающий абонент, является просто ссылкой на копию объекта.
Три способа получить монитор объектов (блокировка) и уведомление ()
В методе потока вызовы wait () и notify () должны указать объект объекта, а поток должен иметь монитор объекта объекта. Самый простой способ получить монитор объекта - это использовать синхронизированное ключевое слово в объекте. После вызова метода wait () поток отпустит блокировку объекта и введет состояние сна. Когда другие потоки вызывают метод notify (), должен использоваться тот же объект объекта.
Для нескольких методов, заблокированных объектом, один из них будет выбран для просыпания при вызове метода notify (), а notifyall () разбудит все свои потоки ожидания.
net.mindview.util; импортировать javax.swing.jframe; открытый класс Frame.SetDefaultCoperation (jframe. exit_on_close); 300, 100); {t = waitAndnotifyThread (WaitAndnotifyjframe.this); .Add (Start); (Пауза); .Add (End); = f; if (isWait) wate (); Как и в коде в приведенном выше примере, если блок синхронного кода удаляется, выполнение выбросит исключение java.lang.illegalmonitorstateexception.
Глядя на JDK, мы видим, что причиной этого исключения является то, что текущий поток не является владельцем этого монитора объекта.
Этот метод должен быть вызван только потоком, который является владельцем этого монитора объекта.
1. Выполнив метод синхронного экземпляра этого объекта, например:
Общественный синхронизированный void n () {notify (); 2. Выполнив тело синхронизированного оператора, которое синхронизируется на этом объекте, например:
public void n () {синхронизированный (this) {notify (); 3. Для объектов типа класса вы можете выполнить синхронные статические методы этого класса.
При вызове статического метода мы не обязательно создаем объект экземпляра. Следовательно, это не может быть использовано для синхронизации статических методов, поэтому объект класса должен использоваться для синхронизации статических методов. Еще один пример, чтобы проиллюстрировать:
Открытый класс SynchronizedStatic реализует Runnable {Private Static Boolean Flag = true; // Метод синхронизации объекта класса ONE: // Обратите внимание на метод синхронизации статической модификации, монитор: SynchronizedStatic.class Pri -vate Static Synchronized void TestSyncmethod () {for (int I = 0; // Метод синхронизации объекта класса. Это то же самое, что статический синхронизированный метод неявно получает монитор класса. Синхронизированный (SynchronizedStatic ("testSyncblock:" + i); Следовательно, разные потоки будут выполнять различные методы, и только таким образом вы можете увидеть разные эффекты блокировки. if (flag) {flag = false; = new SynchronizedStatic (); Приведенный выше код запускает результат запуска двух методов синхронизации для печати 100 чисел от 0 до 99 одновременно. Блок - это класс. Два метода похожи. Поскольку объем метода один и второй метод являются классами, они являются взаимоисключающими. Следовательно, результатом программы будет:
testsyncmethod: 0testsyncmethod: 1 ... ... testsyncmethod: 99testsyncblock: 0 ... ... testsyncblock: 99
Однако, если мы заменим SynchronizedStatic.
testsyncblock: 0testsyncmethod: 0testsyncblock: 1testsyncmethod: 1 ... ... testsyncmethod: 99testsyncblock: 99
Есть две сферы замков, одна - это объект класса, а другой - сам класс. В приведенном выше коде дается два метода, чтобы сделать сферу блокировки класса, чтобы синхронизация могла быть завершена между различными объектами одного и того же класса.
Подводя итог, необходимо отметить следующие моменты:
1. wait (), notify () и notifyall () все необходимо выполнить в соответствии с тем, чтобы иметь монитор объекта, в противном случае будет брошена java.lang.illegalmonitorstateexception.
2. Несколько потоков могут ждать на одном объекте одновременно.
3. notify () - это случайным образом разбудить поток, ожидающий объекта.
4. Поток, который пробуждается Notify (), не просыпается сразу после выполнения notify (), но только после того, как поток notify () выпускает монитор объекта.
5. Эти методы объекта все еще далеки от методов сна и прерывания, поэтому не путайте их.