Порядок выполнения потоков, ожидающих синхронизированный блок
У меня работает несколько потоков, и все пытаются войти в синхронизированный блок.
Я заметил, что поток работает в случайном порядке (когда я вызываю 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, если вы хотите справедливый доступ к синхронизированному блоку.
Мой вопрос: последний поток пришел в ожидании получает синхронизированный блок первым?
Краткий ответ - нет.
Многопоточный механизм не дает такой возможности управлять порядком пробуждения. Это зависит от многих факторов, какая нить просыпается и в каком порядке. Вы должны управлять этим вручную. Создайте некоторую разделяемую переменную или стек, и если поток еще не предполагается работать - выведите его и подождите, пока он не получит контроль. И затем сделайте это снова, пока время / заказ не будет правильным.