multithreading - Synchronizing multiple threads JAVA -
i have 200 students waiting enter room 200 seats (25 rows , 8 columns). door capacity 4 people. when student enter room, chooses random seat (row , column). if chosen seat @ 9th row or less takes 1 second sit, on 18th , less takes 2 seconds, , if 18 25 takes 3 seconds. when of them take seat person must come in room. problem when first 4 people enter room take seat 1 one , not @ once. how can fix that? example if 2 people choose seat @ 5th row both need sit 1 seconds , 2 new students must enter room.
public class student { int row; int column; volatile static int mutex; //generating random numbers row , column public student(seats[][] seats) { this.row = (int) math.ceil(math.random() * 25); this.column = (int) math.ceil(math.random() * 8); if (!seats[row][column].istaken) { seats[row][column].istaken = true; } else { { this.row = (int) math.ceil(math.random() * 25); this.column = (int) math.ceil(math.random() * 8); } while (!seats[row][column].istaken); seats[row][column].istaken = true; } } /*check if mutex 4 (4 people in room) wait if enter room increment mutex*/ synchronized void add() throws interruptedexception { while (mutex > 4) wait(); student.mutex++; notifyall(); } /* check if mutex 0 (no 1 in room) wait if student has sit - decrement mutex , notify*/ synchronized void takeseat() throws interruptedexception { while (mutex == 0) wait(); student.mutex--; notifyall(); } } class seats { int seat; boolean istaken; public seats(int seat) { this.seat = seat; this.istaken = false; } } class studentthread extends thread { seats[][] seats = new seats[25][8]; studentthread(seats[][] seats) { this.seats = seats; } public void run() { try { student student = new student(seats); synchronized (seats) { system.out.println("student enter room"); /*call synchronized method student increment mutex*/ student.add(); if (student.mutex == 4) { if (student.row <= 9) { sleep(1000); student.takeseat(); system.out.println("student take seat @ " + student.row + " " + student.column); } if (student.row <= 18 && student.row > 9) { sleep(2000); student.takeseat(); system.out.println("student take seat @ " + student.row + " " + student.column); } if (student.row <= 25 && student.row > 18) { sleep(3000); student.takeseat(); system.out.println("student take seat @ " + student.row + " " + student.column); } } } } catch (interruptedexception e) { e.printstacktrace(); } } } class main { public static void main(string[] args) { seats[][] seats = new seats[25][8]; //initializing seats (int = 0; < 25; i++) (int j = 0; j < 8; j++) { seats[i][j] = new seats(i); } (int = 0; < 200; i++) { studentthread t1 = new studentthread(seats); t1.start(); } } }
use semaphore, practical these kind of things.
to make example bit more realistic: imagine need 200 http get-requests, server ban if run more 4 requests @ same time. example below shows how can limit number of requests running @ same time using semaphore.
import java.util.random; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.semaphore; public class resourceusagelimiter { static executorservice executor = executors.newcachedthreadpool(); static int requests = 20; static int maxrequestsconcurrent = 4; static int maxrequesttime = 1000; static random randomizer = new random(); static semaphore openslots = new semaphore(maxrequestsconcurrent); static long starttime = system.currenttimemillis(); public static void main(string[] args) { try { (int = 0; < requests; i++) { openslots.acquire(); executor.execute(new requestrunner(i)); } } catch (exception e) { e.printstacktrace(); } { executor.shutdown(); } } static long time() { return system.currenttimemillis() - starttime; } static class requestrunner implements runnable { int sleeptime, reqid; public requestrunner(int reqid) { this.reqid = reqid; sleeptime = randomizer.nextint(maxrequesttime); } @override public void run() { try { system.out.println(time() + " " + reqid + " sleeping " + sleeptime); thread.sleep(sleeptime); system.out.println(time() + " " + reqid + " sleep done"); } catch (exception e) { e.printstacktrace(); } { openslots.release(); } } } }
ofcourse, way limit maximum number of requests running @ same time in example use thread pool fixed size of 4.
Comments
Post a Comment