Скопируйте код кода следующим образом:
общедоступный синхронизированный недействительный запуск()
{
}
Как видно из приведенного выше кода, если между void и public добавлено ключевое слово Synchronized, метод run может быть синхронизирован. То есть для экземпляра объекта одного и того же класса Java метод run может быть только синхронизирован. вызывается одним потоком одновременно и может быть вызван другими потоками только после выполнения текущего выполнения. Даже если текущий поток выполняет метод yield в методе run, он приостанавливается лишь на некоторое время. Поскольку другие потоки не могут выполнить метод run, текущий поток в конечном итоге продолжит выполнение. Сначала взгляните на следующий код:
Ключевое слово sychronized привязано только к одному экземпляру объекта.
Скопируйте код кода следующим образом:
классный тест
{
публичный синхронизированный метод void()
{
}
}
общедоступный класс Sync реализует Runnable
{
частный тестовый тест;
публичный недействительный запуск()
{
тест.метод();
}
публичная синхронизация (тестовый тест)
{
this.test = тест;
}
public static void main(String[] args) выдает исключение
{
Тест test1 = новый тест();
Тест test2 = новый тест();
Синхронизация sync1 = новая синхронизация (test1);
Синхронизация sync2 = новая синхронизация (test2);
новый поток(sync1).start();
новый поток(sync2).start();
}
}
Методы метода в классе Test являются синхронными. Но приведенный выше код создает два экземпляра класса Test, поэтому методы методов test1 и test2 выполняются отдельно. Чтобы синхронизировать методы, вы должны передать экземпляр того же класса Test в его конструктор при создании экземпляра класса Sync, как показано в следующем коде:
Синхронизация sync1 = новая синхронизация (test1);
Вы можете использовать не только для синхронизации нестатических методов, но и для синхронизации статических методов. Например, метод метода можно определить следующим образом:
Скопируйте код кода следующим образом:
классный тест
{
публичный статический синхронизированный метод void() { }
}
Создайте экземпляр объекта класса Test следующим образом:
Тестовый тест = новый тест();
Для статических методов, если добавлено ключевое слово Synchronized, метод синхронизируется. Независимо от того, используете ли вы test.method() или Test.method() для вызова метода метода, метод синхронизируется и не существует проблемы с несколькими. экземпляры нестатических методов.
Среди 23 шаблонов проектирования режим Singleton также является небезопасным для потоков, если он разработан в соответствии с традиционными методами. Следующий код представляет собой небезопасный для потоков режим Singleton.
Скопируйте код кода следующим образом:
тест упаковки;
// Потокобезопасный одноэлементный режим
класс Синглтон
{
частный статический образец Singleton;
частный синглтон()
{
}
публичный статический синглтон getInstance()
{
если (образец == ноль)
{
Thread.yield(); // Чтобы усилить небезопасность потоков в режиме Singleton
образец = новый синглтон();
}
возвратный образец;
}
}
публичный класс MyThread расширяет поток
{
публичный недействительный запуск()
{
Синглтон синглтон = Singleton.getInstance();
System.out.println(singleton.hashCode());
}
public static void main(String[] args)
{
Потоки[] = новая тема[5];
for (int i = 0; i < threads.length; i++)
потоки [я] = новый MyThread();
for (int i = 0; i < threads.length; i++)
потоки[i].start();
}
}
В приведенном выше коде вызывается метод доходности, чтобы показать небезопасность потока в одноэлементном режиме. Если эту строку удалить, приведенная выше реализация по-прежнему будет небезопасной для потоков, но вероятность возникновения этого события намного меньше.
Результаты запуска программы следующие:
Скопируйте код кода следующим образом:
25358555
26399554
7051261
29855319
5383406
Приведенные выше результаты запуска могут различаться в разных средах выполнения, но, как правило, пять строк вывода не будут полностью одинаковыми. Как видно из этого вывода, с помощью метода getInstance получено пять экземпляров объекта, а не один, как мы ожидали. Это связано с тем, что когда поток выполняет Thread.yield(), он передает ресурсы ЦП другому потоку. Поскольку оператор создания экземпляра объекта Singleton не выполняется при переключении между потоками, все эти потоки проходят проверку if, поэтому будет создано пять экземпляров объекта (можно создать четыре или три экземпляра объекта, в зависимости от количества потоков). решение if перед созданием объекта Singleton, результат может отличаться при каждом его запуске).
Чтобы сделать описанный выше одноэлементный режим потокобезопасным, просто добавьте ключевое слово Synchronized в getInstance. Код выглядит следующим образом:
общедоступный статический синхронизированный синглтон getInstance() { }
Конечно, есть более простой способ — создать объект Singleton при определении переменной Singleton. Код выглядит следующим образом:
частный статический окончательный образец синглтона = новый синглтон();
Затем просто верните образец непосредственно в метод getInstance. Хотя этот метод прост, он не обеспечивает гибкости при создании объекта Singleton в методе getInstance. Читатели могут использовать различные методы для реализации шаблона Singleton в соответствии с конкретными потребностями.
При использовании ключевого слова Synchronized следует учитывать четыре момента:
1. Ключевое слово синхронизации не может быть унаследовано.
Хотя вы можете использовать синхронизированный для определения методов, синхронизированный не является частью определения метода, поэтому ключевое слово синхронизированное не может быть унаследовано. Если метод в родительском классе использует ключевое слово Synchronized и этот метод переопределен в подклассе, метод в подклассе не синхронизируется по умолчанию и должен быть явно указан в подклассе. Просто добавьте ключевое слово Synchronized в метод. Конечно, вы также можете вызвать соответствующий метод родительского класса в методе подкласса. Таким образом, хотя метод в подклассе не является синхронным, подкласс вызывает метод синхронизации родительского класса. подкласс эквивалентен синхронизации. Примеры кодов для этих двух методов следующие:
Добавьте ключевое слово Synchronized в метод подкласса.
Скопируйте код кода следующим образом:
класс Родитель
{
публичный синхронизированный метод void() { }
}
класс Child расширяет родителя
{
публичный синхронизированный метод void() { }
}
Вызов синхронизированного метода родительского класса в методе подкласса
Скопируйте код кода следующим образом:
класс Родитель
{
публичный синхронизированный метод void() { }
}
класс Child расширяет родителя
{
общественный недействительный метод () { super.method () };
}
2. Ключевое слово Synchronized нельзя использовать при определении методов интерфейса.
3. Конструктор не может использовать ключевое слово Synchronized, но может использовать для синхронизации блок Synchronized, который будет обсуждаться в следующем разделе.
4. Синхронизированные файлы могут быть размещены свободно.
В предыдущих примерах ключевое слово Synchronized помещается перед типом возвращаемого значения метода. Но это не единственное место, где можно разместить синхронизацию. В нестатических методах синхронизированный также может быть помещен в начале определения метода. В статических методах синхронизированный может быть помещен перед статическим. Код выглядит следующим образом:
Скопируйте код кода следующим образом:
публичный синхронизированный метод void();
синхронизированный метод public void();
публичный статический синхронизированный метод void();
публичный синхронизированный статический метод void();
синхронизированный метод public static void();
Но обратите внимание, что синхронизированный не может быть помещен после типа возвращаемого значения метода. Например, следующий код неверен:
Скопируйте код кода следующим образом:
публичный недействительный синхронизированный метод();
публичный статический недействительный синхронизированный метод();
Ключевое слово синхронизировано можно использовать только для синхронизации методов, а не переменных класса. Следующий код также неверен.
Скопируйте код кода следующим образом:
общедоступное синхронизированное целое число n = 0;
общедоступный статический синхронизированный int n = 0;
Хотя использование метода синхронизации по ключевому слову является самым безопасным методом синхронизации, интенсивное использование ключевого слова синхронизировано приведет к ненужному потреблению ресурсов и снижению производительности. Хотя на первый взгляд кажется, что синхронизация блокирует метод, на самом деле синхронизация блокирует класс. Другими словами, если синхронизация используется при определении обоих нестатических методов: метода1 и метода2, метод2 не может быть выполнен до того, как будет выполнен метод1. Ситуация аналогична для статических и нестатических методов. Но статические и нестатические методы не влияют друг на друга. Взгляните на следующий код:
Скопируйте код кода следующим образом:
тест упаковки;
публичный класс MyThread1 расширяет поток
{
имя открытого метода String;
общедоступный статический метод void (String s)
{
System.out.println(s);
пока (правда)
}
общедоступный синхронизированный метод void1()
{
метод("нестатический метод метода1");
}
публичный синхронизированный метод void2()
{
метод("нестатический метод метода2");
}
общедоступный статический синхронизированный метод void3()
{
метод("метод статический метод3");
}
общедоступный статический синхронизированный метод void4()
{
метод("статический метод метода4");
}
публичный недействительный запуск()
{
пытаться
{
getClass().getMethod(имя метода).invoke(this);
}
поймать (Исключение e)
{
}
}
public static void main(String[] args) выдает исключение
{
MyThread1 myThread1 = новый MyThread1 ();
для (int я = 1; я <= 4; я++)
{
myThread1.methodName = «метод» + String.valueOf(i);
новый поток (myThread1).start();
спать(100);
}
}
}
Результаты бега следующие:
Скопируйте код кода следующим образом:
Нестатический метод метода1
Статический метод3 метод
Из приведенных выше результатов выполнения видно, что методы 2 и 4 не могут быть запущены до завершения методов 1 и 3. Следовательно, мы можем сделать вывод, что если вы используете ключевое слово Synchronized для определения нестатического метода в классе, это повлияет на все нестатические методы, определенные с использованием ключевого слова Synchronized в этом классе. Если определен статический метод, он повлияет на все статические методы, определенные с использованием ключевого слова Synchronized в классе. Это немного похоже на блокировку таблицы в таблице данных. При изменении записи система блокирует всю таблицу. Поэтому широкое использование этого метода синхронизации значительно снизит производительность программы.