#java #multithreading #semaphore
#java #многопоточность #семафор
Вопрос:
я создал 2 потока для 2 поездов, первый имеет направление (север-юг), а второй — направление (юг-север), поэтому есть только одна железная дорога, не могу встретить 2 поезда с разным направлением .. итак, вот мой основной класс :
public static void main(String[] args) throws InterruptedException {
Semaphore sem = new Semaphore(1);
MyThread train1 = new MyThread(sem, "nord-sud");
MyThread train2 = new MyThread(sem, "sud-nord");
// stating threads 1 and train 2
train1.start();
train2.start();
train1.join();
train2.join();
}
и вот мой класс MyThread расширенный класс потоков :
class MyThread extends Thread
{
Semaphore sem;
String threadName;
public MyThread(Semaphore sem, String threadName)
{
super(threadName);
this.sem = sem;
this.threadName = threadName;
}
@Override
public void run() {
// run by thread A
if(this.getName().equals("nord-sud"))
{
System.out.println("Starting " threadName);
try
{
System.out.println(threadName " wait for railway to enter");
// acquiring the lock
sem.acquire();
System.out.println(threadName " have access to enter");
// Now, accessing the shared resource.
// other waiting threads will wait, until this
// thread release the lock
for(int i=0; i < 5; i )
{
Shared.count ;
System.out.println(threadName ": " i);
// Now, allowing a context switch -- if possible.
// for thread B to execute
Thread.sleep(1000);
}
} catch (InterruptedException exc) {
System.out.println(exc);
}
// Release the permit.
System.out.println(threadName " left the railway ");
sem.release();
}
// run by thread B
else
{
System.out.println("Starting " threadName);
try
{
// First, get a permit.
System.out.println(threadName " wait for railway to enter");
sem.acquire();
System.out.println(threadName " have access to enter");
for(int i=0; i < 5; i )
{
Shared.count--;
System.out.println(threadName ": " i);
Thread.sleep(1000);
}
} catch (InterruptedException exc) {
System.out.println(exc);
}
// Release the permit.
System.out.println(threadName "left the railway");
sem.release();
}
}
}
поэтому, когда я добавляю 2 поезда с направлением север-юг, например, за тот же период, я хочу, чтобы они оба получили ввод на железную дорогу, потому что у них одинаковое направление, поезд должен ждать только тогда, когда он поймет, что другой поезд с другим направлением находится на железной дороге. итак, как я могу выполнить 2 потока одновременно? например, train1 (nord-sud), train2 (nord-sud) и train3 (sud-nord). таким образом, как поезд 1, так и поезд 2 входят в железнодорожный, а поезд 3 ждет, пока они уйдут, чтобы получить доступ.
Комментарии:
1. Почему
if... else...
блок? Вы запускаете точно такой же код в обеих ветвях.
Ответ №1:
Вы можете создать два разрешения для поездов с одинаковыми направлениями и одно разрешение для поездов с разными направлениями, например:
public class Solution0 {
public static void main(String[] args) throws InterruptedException {
String direction1 = "nord-sud";
String direction2 = "sud-sud";
int permissionCount;
if (direction1.equals(direction2)){
permissionCount = 2;
}else {
permissionCount = 1;
}
Semaphore sem = new Semaphore(permissionCount);
MyThread train1 = new MyThread(sem, direction1);
MyThread train2 = new MyThread(sem, direction2);
// stating threads 1 and train 2
train1.start();
train2.start();
train1.join();
train2.join();
}
}
вывод для другого направления:
Starting sud-sud
Starting nord-sud
sud-sud wait for railway to enter
nord-sud wait for railway to enter
sud-sud have access to enter
sud-sud: 0
sud-sud: 1
sud-sud: 2
sud-sud: 3
sud-sud: 4
sud-sudleft the railway
nord-sud have access to enter
nord-sud: 0
nord-sud: 1
nord-sud: 2
nord-sud: 3
nord-sud: 4
nord-sud left the railway
вывод для аналогичного направления:
Starting sud-sud
Starting sud-sud
sud-sud wait for railway to enter
sud-sud wait for railway to enter
sud-sud have access to enter
sud-sud have access to enter
sud-sud: 0
sud-sud: 0
sud-sud: 1
sud-sud: 1
sud-sud: 2
sud-sud: 2
sud-sud: 3
sud-sud: 3
sud-sud: 4
sud-sud: 4
sud-sudleft the railway
sud-sudleft the railway
Комментарии:
1. да, но что, если я добавлю 2 поезда с тем же направлением, а затем другой поезд с другим направлением? я хочу, чтобы третий также получил доступ, когда 2 первых поезда покинули железную дорогу.
Ответ №2:
В этом случае вы должны создать список и поток для каждого из поездов nord-sud и sud-nord. Потоки списка должны отвечать за получение семафора, затем при получении они должны запускать отдельные потоки поездов (предположительно, добавляя задержку с каждым после первого, чтобы поезда не запускались одновременно). Затем поток списка должен вызывать Thread.join() в каждом потоке поезда (хотя на самом деле может потребоваться присоединиться только к последнему), а затем освободить семафор после прибытия последнего поезда.