Java Параллелизм (03): многопоточная параллельный доступ, управление синхронизацией

Эта статья Источник: GitHub · Нажмите здесь || GitEE · Нажмите здесь

Во-первых, вопросы параллельности

Многопоточное обучение, первым столкнулся с сложной проблемой является то, что переменной доступа одновременно режим, если игнорируются четкие внутренние процессы и причинами, часто будет такой проблемой: после нарезания резьбы значения переменного не то, что вы хотите также может выглядеть невежественными сказать: это нелогично правильно?

1, переменные-члены доступа

Несколько потоков к переменным-членам класса доступа, это может привести к различным проблемам.

public class AccessVar01 {
    public static void main(String[] args) {
        Var01Test var01Test = new Var01Test() ;
        VarThread01A varThread01A = new VarThread01A(var01Test) ;
        varThread01A.start();
        VarThread01B varThread01B = new VarThread01B(var01Test) ;
        varThread01B.start();
    }
}
class VarThread01A extends Thread {
    Var01Test var01Test = new Var01Test() ;
    public VarThread01A (Var01Test var01Test){
        this.var01Test = var01Test ;
    }
    @Override
    public void run() {
        var01Test.addNum(50);
    }
}
class VarThread01B extends Thread {
    Var01Test var01Test = new Var01Test() ;
    public VarThread01B (Var01Test var01Test){
        this.var01Test = var01Test ;
    }
    @Override
    public void run() {
        var01Test.addNum(10);
    }
}
class Var01Test {
    private Integer num = 0 ;
    public void addNum (Integer var){
        try {
            if (var == 50){
                num = num + 50 ;
                Thread.sleep(3000);
            } else {
                num = num + var ;
            }
            System.out.println("var="+var+";num="+num);
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

Случаи, когда поток является параллельной работой с переменным членом, программа предназначена для: вара = 50, чтобы получить номер = 50, фактические результаты вывода являются:

var=10;num=60
var=50;num=60

Обработка резьбы VarThread01A переходит в спящий режим, Num было проведено нитью VarThread01B время сна плюс 10 операции, которая является результатом многопоточного параллельного доступа из-за.

2. Метод частных переменных

Логика изменить приведенный выше код, размещенный в методе переменной NUM, как методы частного переменный.

class Var01Test {
    // private Integer num = 0 ;
    public void addNum (Integer var){
        Integer num = 0 ;
        try {
            if (var == 50){
                num = num + 50 ;
                Thread.sleep(3000);
            } else {
                num = num + var ;
            }
            System.out.println("var="+var+";num="+num);
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

Внутренние переменные метода являются частными, и один ток и поток исполнения метод, не будет никаких помех между потоками.

Во-вторых, управление синхронизации

1, синхронизированной ключевое слово

способы модификации, либо в виде контроля блоков синхронизации, что обеспечивает несколько потоков одновременно, только один поток в то время, в процесс, или блок кода синхронизации, так что поточно-доступ и переменный процесс: использование. Если модификация является статическим методом, роль всех объектов этого класса.

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

2, способы модификации

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

public class AccessVar02 {
    public static void main(String[] args) {
        Var02Test var02Test = new Var02Test ();
        VarThread02A varThread02A = new VarThread02A(var02Test) ;
        varThread02A.start();
        VarThread02B varThread02B = new VarThread02B(var02Test) ;
        varThread02B.start();
        var02Test.readValue();
    }
}
class VarThread02A extends Thread {
    Var02Test var02Test = new Var02Test ();
    public VarThread02A (Var02Test var02Test){
        this.var02Test = var02Test ;
    }
    @Override
    public void run() {
        var02Test.change("my","name");
    }
}
class VarThread02B extends Thread {
    Var02Test var02Test = new Var02Test ();
    public VarThread02B (Var02Test var02Test){
        this.var02Test = var02Test ;
    }
    @Override
    public void run() {
        var02Test.change("you","age");
    }
}
class Var02Test {
    public String key = "cicada" ;
    public String value = "smile" ;
    public synchronized void change (String key,String value){
        try {
            this.key = key ;
            Thread.sleep(2000);
            this.value = value ;
            System.out.println("key="+key+";value="+value);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public void readValue (){
        System.out.println("读取:key="+key+";value="+value);
    }
}

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

3, логика управления синхронизацией

Реализация объекта основан на мониторе управления синхронизацией.

  • доступ к Thread Object, Object Сначала получите монитор;
  • Если приобретение успешно, цель будет эксклюзивом;
  • Другие потоки будут падать в синхронизации очереди, состояние потока блокируется;
  • Владельцы объектов и другие выпуски нити замок, нить будет пробуждать в очереди, попробуйте перезагрузить объект приобретать мониторы;

4, модифицированные блоки кода

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

public class AccessVar03 {
    public static void main(String[] args) {
        Var03Test var03Test1 = new Var03Test() ;
        Thread thread1 = new Thread(var03Test1) ;
        thread1.start();
        Thread thread2 = new Thread(var03Test1) ;
        thread2.start();
        Thread thread3 = new Thread(var03Test1) ;
        thread3.start();
    }
}
class Var03Test implements Runnable {
    private Integer count = 0 ;
    public void countAdd() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized(this) {
            count++ ;
            System.out.println("count="+count);
        }
    }
    @Override
    public void run() {
        countAdd() ;
    }
}

Вот код для основной обработки логики подсчета блокировки действия, не позволяет параллельной обработки.

5, модифицированный статический метод

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

public class AccessVar04 {
    public static void main(String[] args) {
        Var04Test var04Test1 = new Var04Test() ;
        Thread thread1 = new Thread(var04Test1) ;
        thread1.start();
        Var04Test var04Test2 = new Var04Test() ;
        Thread thread2 = new Thread(var04Test2) ;
        thread2.start();
    }
}
class Var04Test implements Runnable {
    private static Integer count ;
    public Var04Test (){
        count = 0 ;
    }
    public synchronized static void countAdd() {
        System.out.println(Thread.currentThread().getName()+";count="+(count++));
    }
    @Override
    public void run() {
        countAdd() ;
    }
}

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

Thread-0;count=0
Thread-1;count=0

После добавления элемента управления синхронизации, фактического выхода теста:

Thread-0;count=0
Thread-1;count=1

6 Примечания

  • Наследование нейтрон родительский класс переопределяет метод, синхронизированный ключ передачи не наследуют характеристики, должны быть явно объявлены;
  • Синхронное ключевое слово не может быть использовано на методе строительства, при поддержке конструктора блока синхронизации;
  • Интерфейс метода, абстрактный метод не поддерживает синхронное ключевое слово;

Три, Летучие ключевое слово

1, основное описание

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

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

2, Прецеденты

class Var05Test {
    private volatile boolean myFlag = true ;
    public void setFlag (boolean myFlag){
        this.myFlag = myFlag ;
    }
    public void method() {
        while (myFlag){
            try {
                System.out.println(Thread.currentThread().getName()+myFlag);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

3 Примечания

  • Видимость только для того, чтобы каждый прочитал последнее значение, но не поддерживает операцию атомной переменную;
  • летучие и не блокирует метод резьбы, но будет блокировать контроль синхронизации;
  • Java управления синхронизацией фундаментальна: обеспечить атомарность и видимость с низшими ресурсов;

В-четвертых, адрес источника

GitHub·地址
https://github.com/cicadasmile/java-base-parent
GitEE·地址
https://gitee.com/cicadasmile/java-base-parent

Java Параллелизм (03): многопоточная параллельный доступ, управление синхронизацией

рекомендация

отblog.51cto.com/14439672/2482929
рекомендация