1. Синхронная проблема поднята
Синхронизация потока заключается в предотвращении повреждения данных, когда несколько потоков получают доступ к объекту данных.
Например: оба потока Threada и Threadb работают с одним и тем же объектом Foo и изменяют данные на объекте Foo.
Пакет CN.Thread; открытый класс foo {private int x = 100; public int getx () {return x; } public int fix (int y) {x = x - y; возврат x; }} Пакет Cn.Thread; открытый класс MyRunnable Reflsements Runnable {private foo foo = new foo (); public static void main (string [] args) {myrunnable run = new myrunnable (); Thread TA = новый поток (run, "Thread-A"); Thread TB = новый поток (run, "Thread-B"); ta.start (); TB.Start (); } public void run () {for (int i = 0; i <3; i ++) {this.fix (30); try {thread.sleep (1); } catch (прерванное искусство e) {e.printstacktrace (); } System.out.println (think.currentThread (). GetName () + ": x значение текущего объекта foo =" + foo.getx ()); }} public int fix (int y) {return foo.fix (y); }}Результаты работы:
Thread-B: значение x текущего объекта Foo = 40
Thread-A: Значение x текущего объекта Foo = 40
Thread -B: значение x текущего объекта Foo = -20
Thread -A: Значение x текущего объекта Foo = -20
Thread -B: значение x текущего объекта Foo = -80
Thread -A: Значение x текущего объекта Foo = -80
Из результатов было обнаружено, что такое выходное значение было явно необоснованным. Причина в том, что два потока получают доступ к объектам FOO без контроля и изменяют их данные.
Если вы хотите сохранить рациональность результатов, вам нужно достичь только одной цели, которая состоит в том, чтобы ограничить доступ к FOO, и только один поток может получить к нему доступ. Это обеспечит рациональность данных в объекте Foo.
В конкретном коде Java необходимо завершить две операции:
Определите переменную Foo x класса ресурсов, которая посещается конкуренцией как частная;
Синхронизируйте код, который изменяет переменные, и используйте синхронизированное ключевое слово для синхронизации метода или кода.
пакет cn.thread; открытый класс foo2 {private int x = 100; public int getx () {return x; } // Синхронизированный метод публичный синхронизированный int fix (int y) {x = x - y; System.out.println ("Thread" + Thread.currentThread (). GetName () + "Запуск окончания, уменьшить" + y + "" ", текущее значение:" + x); возврат x; } // // Синхронизированный кодовый блок // public int fix (int y) {// synchronized (this) {// x = x - y; // system.out.println ("Thread" + thread.currentThread (). GetName () + "Запуск, уменьшается" " + y // +" ", товое значение -" + x); пакет cn.thread; public class myrunnable2 {public static void main (string [] args) {myrunnable2 run = new myrunnable2 (); Foo2 foo2 = new foo2 (); Mythread t1 = run.new mythread ("thread a", foo2, 10); Mythread t2 = run.new mythread ("thread b", foo2, -2); Mythread t3 = run.new mythread ("Thread C", foo2, -3); Mythread t4 = run.new mythread ("Thread D", Foo2, 5); t1.start (); t2.start (); t3.start (); t4.start (); } класс Mythread Extends Thread {private foo2 foo2; / ** Текущее значение*/ private int y = 0; Mythread (string name, foo2 foo2, int y) {super (name); this.foo2 = foo2; this.y = y; } public void run () {foo2.fix (y); }}} Надпись заканчивается, уменьшает «10», текущее значение: 90
Поток C запускается и заканчивается, уменьшает «-3», текущее значение: 93
Поток B работает в конце, уменьшает «-2», текущее значение: 95
Поток D запускается и заканчивается, уменьшает «5», текущее значение: 90
2. Синхронизация и блокировка
1. Принцип блокировки
Каждый объект в Java имеет встроенный замок.
Когда программа работает на нестатическом методе синхронизированной синхронизации, блокировка, связанная с текущим экземпляром выполняемого класса кода (этот экземпляр). Замок, который приобретает объект, также называется получением блокировки, блокируя объект, блокируя объект или синхронизируя на объекте.
Блокировка объекта работает только тогда, когда программа работает в методе синхронизированной синхронизации или блока кода.
Есть только один замок для объекта. Таким образом, если нить приобретает блокировку, ни один другой поток не сможет получить блокировку, пока первый поток не выпустит (или возвращает) блокировку. Это также означает, что ни один другой поток не может ввести синхронизированный метод или блок кода в объект, пока не будет выпущена блокировка.
Выпуск блокировки означает, что поток блокировки выходит из метода синхронизированной синхронизации или блока кода.
Есть несколько ключевых моментов о блокировке и синхронизации:
1) только методы могут быть синхронизированы, но переменные и классы не могут быть синхронизированы;
2) у каждого объекта есть только один замок; Когда дело доходит до синхронизации, что должно быть ясно? То есть, на каком объекте синхронизируется?
3) Нет необходимости синхронизировать все методы в классе. Занятия могут иметь как синхронные, так и асинхронные методы.
4) Если два потока хотят выполнить синхронизированный метод в одном классе, а два потока используют один и тот же экземпляр для вызова метода, то только один поток может выполнять метод за раз, а другой должен ждать, пока не будет выпущена блокировка. То есть: если поток получает блокировку на объекте, ни один другой поток не может ввести какой -либо метод синхронизации в классе (этого объекта).
5) Если поток имеет синхронизацию и асинхронные методы, асинхронные методы могут быть свободно доступны с помощью нескольких потоков, не ограничиваясь замками.
6) Когда нить спит, не будет выпущена блокировка.
7) потоки могут получить несколько замков. Например, вызов метода синхронизации другого объекта в методе синхронизации одного объекта приобретет блокировку синхронизации двух объектов.
8) Синхронизация ухудшает параллелизм и должна максимально сузить диапазон синхронизации. Синхронизация может не только синхронизировать весь метод, но и синхронизировать некоторые кодовые блоки в методе.
9) При использовании блоков кода синхронизации вы должны указать, какой объект синхронизировать, то есть какой блокировку объекта должен быть получен. Например:
public int fix (int y) {synchronized (this) {x = x - y; } return x;} Конечно, метод синхронизации также может быть переписан в качестве асинхронного метода, но функции точно такие же: например:
public Synchronized int getx () {return x ++;} и
public int getx () {synchronized (this) {return x ++; }}Эффект точно такой же.
3. Статический метод синхронизация
Чтобы синхронизировать статические методы, для всего объекта класса необходима блокировка, который является этим классом (xxx.class).
Например:
Public Static Synchronized int setName (String name) {xxx.name = name;}
Эквивалентно
public static int setName (string name) {synchronized (xxx.class) {xxx.name = name; }}4. Что произойдет, если поток не может получить блокировку
Если поток пытается войти в синхронный метод, и его блокировка была занята, поток блокируется на объекте. По сути, поток попадает в пул объекта и должен ждать, где он должен подождать, пока его блокировка не будет выпущена, и поток не станет запустить или снова запустить.
При рассмотрении блокировки обязательно обратите внимание на какой объект используется для блокировки:
1. потоки, которые вызывают нестатические методы синхронизации в одном и том же объекте, будут блокировать друг друга. Если это другой объект, каждый поток имеет свою собственную блокировку объекта, а потоки не мешают друг другу.
2. потоки, которые вызывают методы статической синхронизации в одном и том же классе, будут блокировать друг друга, и все они заблокированы на одном объекте класса.
3. Методы статической синхронизации и нестатические методы синхронизации никогда не будут блокировать друг друга, потому что статические методы заблокированы на объектах класса, в то время как нестатические методы заблокированы на объектах этого класса.
4. Для синхронизированных кодовых блоков вам нужно четко увидеть, какие объекты были использованы для блокировки (содержимое синхронизированных кронштейнов после синхронизации). Синхронизированные потоки на одном и том же объекте будут блокировать друг друга, и потоки, заблокированные на разных объектах, никогда не будут блокировать друг друга.
5. Когда необходимо синхронизировать
Когда несколько потоков получают доступ к взаимоисключающим (обменным) данным одновременно, их следует синхронизировать для защиты данных, гарантируя, что оба потока не изменяют и изменяют их одновременно.
Для данных, которые могут быть изменены в нестатических полях, обычно обращаются нестатические методы.
Для данных, которые могут быть изменены в статическом поле, к ним обычно обращается с использованием статического метода.
Проблема становится очень сложной, если вам нужно использовать статические поля в нестатических методах или вызовать нестатические методы в статических полях. Он превысил объем экзамена SJCP.
6. Категория безопасности потока
Когда класс хорошо синхронизирован для защиты своих данных, этот класс называется «безопасным потоком».
Даже для безрезультатных классов вы должны быть очень осторожны, потому что действующие потоки все еще не обязательно безопасны.
7. Сводка синхронизации потока
1. Цель синхронизации потока состоит в том, чтобы защитить повреждение ресурсов, когда несколько потоков получают доступ к ресурсу.
2. Метод синхронизации потока реализован через блокировки. У каждого объекта есть только один замок. Этот замок связан с конкретным объектом. Как только поток получает блокировку объекта, другие потоки, получающие доступ к объекту, больше не могут получить доступ к другим методам синхронизации объекта.
3. Для методов статической синхронизации блокировки предназначены для этого класса, а объекты блокировки являются объектами класса этого класса. Замки статических и нестатических методов не мешают друг другу. Поток получает блокировку, и при доступе к методу синхронизации на другом объекте в методе синхронизации он получает эти два блокировки объектов.
4. Для синхронизации это ключ к тому, чтобы всегда знать, какой объект синхронизировать.
5. При написании безрезультатных классов вам необходимо всегда обращать внимание на правильные суждения о логике и безопасность нескольких потоков, конкурирующих за доступ к ресурсам, анализировать операции «атомные» и гарантировать, что другие потоки не могут получить доступ к конкурирующим ресурсам во время атомной операции.
6. Когда несколько потоков ждут блокировки объекта, поток, который не получил блокировку, будет блокировать.
7. Тупика вызвана потоками, ожидающими блокировки друг друга, и вероятность возникновения в действительности очень мала. Если вы действительно хотите написать программу Deadlock, это может быть нелегко в использовании, ха -ха. Однако, как только программа умрет, программа умрет.
Оригинальная ссылка: http://www.cnblogs.com/linjiqin/p/3208843.html
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.