Порядок выполнения потоков, ожидающих синхронизированный блок

У меня работает несколько потоков, и все пытаются войти в синхронизированный блок.

Я заметил, что поток работает в случайном порядке (когда я вызываю Thread.start()), это нормально

когда первый поток исполняется и входит в синхронизированный метод, он засыпает.

в течение этого периода приходят другие потоки и начинают ждать освобождения синхронизированного блока.

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

Ниже приведен код.

 import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.sql.rowset.Joinable;


public class ThreadOrdering{  public static void main(String... args) {
    Results results = new Results();
    Thread a=   new Thread(new Task(0, "red", results));
    a.start();

    Thread b=  new Thread(new Task(1, "orange", results));
    b.start();

    Thread c=    new Thread(new Task(2, "yellow", results));
    c.start();

    Thread d= new Thread(new Task(3, "green", results));
    d.start();

    Thread e= new Thread(new Task(4, "blue", results));
    e.start();



}
}

class Results {
private List<String> results = new ArrayList<String>();
private int i = 0;

public synchronized void submit(int order, String result) {
     System.out.println("synchronized accupied by: " + order + " " + result);
       try {
        Thread.sleep((long)(Math.random() *1000));
         System.out.println("synchronized released by: " + order + " " + result);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}
}


class Task implements Runnable {
private final int order;
private final String result;
private final Results results;

public Task(int order, String result, Results results) {
    this.order = order;
    this.result = result;
    this.results = results;
}

public void run() {

     System.out.println("run  by: " + order + " " + result);

    results.submit(order, result);

}
}

Пример вывода:

в ведении: 1 оранжевый

синхронизировано: 1 оранжевый

под управлением: 2 желтых

в ведении: 4 синих

под управлением: 0 красный

в ведении: 3 зеленых

синхронизировано выпущено: 1 оранжевый

синхронизируется: 3 зеленых

синхронизировано выпущено: 3 зеленых

синхронизировано: 0 красный

синхронизирован выпущен: 0 красный

Синхронизировано: 4 синих

синхронизировано выпущено: 4 синий

синхронизированы: 2 желтые

синхронизировано выпущено: 2 желтый

как мы видим, порядок выполнения потока является случайным.. это нормально.. 1 2 4 0 3

1 получает синхронизированный блок, а после его окончания 3(последний) получает 0, 4 и 2....

Как сделать этот порядок обратным,,, что после 1 должно быть 2, затем 4, затем 0, затем 3

2 ответа

Вы должны использовать ReentrantLock, если вы хотите справедливый доступ к синхронизированному блоку.

Мой вопрос: последний поток пришел в ожидании получает синхронизированный блок первым?

Краткий ответ - нет.

Многопоточный механизм не дает такой возможности управлять порядком пробуждения. Это зависит от многих факторов, какая нить просыпается и в каком порядке. Вы должны управлять этим вручную. Создайте некоторую разделяемую переменную или стек, и если поток еще не предполагается работать - выведите его и подождите, пока он не получит контроль. И затем сделайте это снова, пока время / заказ не будет правильным.

Другие вопросы по тегам