KDP/Lab 2 RTI 2023

Izvor: SI Wiki
Pređi na navigaciju Pređi na pretragu

Postavka

U zavisnosti od grupe bilo je potrebno rešiti jedan od sledeće dva problema.

1. Rešiti DiningPhilosopher problem koristeći ExecutorService i gde je potrebno da server vraća filozoferu informaciju kada mu je dozvoljeno da jede. Koristiti System.currentTimeMillis() za dohvatanje vremena i dozvonjeno je koristiti Future i druge sinhronizacione primitive za rešavanje zadatka.

2. TODO.

Rešenje

Ispod je dato rešenje za DiningPhilosophers.

Izgled hijerarhije fajlova:

.
├── client
│   └── Philosopher.java
├── common
│   └── Service.java
└── server
    ├── RequestHandler.java
    └── Server.java

Philosopher.java

package client;

import common.Service;

public class Philosopher extends Thread{

    public static final int NUM_OF_PHILOSOPHERS = 30;
    public static int curr_id = 0;
    public int id = 0;
    public Service service;

    public Philosopher(Service service) {
        this.id = curr_id++;

        this.service = service;
    }

    @Override
    public void run() {

        while(true) {
            // think
            try {
                Thread.sleep((long) (Math.random() * 1000));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            this.service.eat(this.id);
        }

    }

    public static void main(String[] args) {

        Philosopher[] arr = new Philosopher[NUM_OF_PHILOSOPHERS];

        Service service = new Service("localhost", 4001);

        for(int i = 0; i < NUM_OF_PHILOSOPHERS; i++) {
            arr[i] = new Philosopher(service);
        }

        for(int i = 0; i < NUM_OF_PHILOSOPHERS; i++) {
            arr[i].start();
        }

    }
}

Service.java

package common;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class Service {


    String host;
    int port;

    public Service(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void eat(int id) {

        try (
                Socket socket = new Socket(this.host, this.port);
                BufferedReader buffered_reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter print_writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
                ) {

            print_writer.println("eat"+"#"+id);

            // Get the resource
            String time = buffered_reader.readLine();
            System.out.println("Filozofer sa id: " + id + " je dobio pristup u trenutku: " + time);

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

RequestHandler.java

package server;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class RequestHandler extends Thread {

    Socket sock;
    Server server;

    public RequestHandler(Socket sock, Server server) {
        this.sock = sock;
        this.server = server;
    }

    @Override
    public void run() {

        try (
                Socket socket = this.sock;
                BufferedReader buffered_reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter print_writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
        ) {

            String in = buffered_reader.readLine();

            String[] data = in.split("#");

            String operation = data[0];
            int id = Integer.parseInt(data[1]);

            if ("eat".equalsIgnoreCase(operation)) {
                server.test(id);
                server.eat(buffered_reader, print_writer);
                server.signal(id);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

Server.java

package server;

import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {

    ExecutorService pool;
    final static int MAX_THREADS = 10;

    public static final int NUM_OF_PHILOSOPHERS = 30;
    int []forks;
    int port;

    public Server(int port) {
        this.forks = new int[NUM_OF_PHILOSOPHERS];

        for(int i = 0; i < NUM_OF_PHILOSOPHERS; i++) {
            forks[i] = 2;
        }

        pool = Executors.newFixedThreadPool(MAX_THREADS);

        this.port = port;
    }

    public synchronized void test(int id) {
        int left = (id - 1 + NUM_OF_PHILOSOPHERS) % NUM_OF_PHILOSOPHERS;
        int right = (id + 1 + NUM_OF_PHILOSOPHERS) % NUM_OF_PHILOSOPHERS;

        while(forks[id] != 2) {
            try {
                wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        forks[left]--;
        forks[right]--;


    }

    public void eat(BufferedReader rd, PrintWriter pw) {
        pw.println(System.currentTimeMillis());
    }


    public synchronized void signal(int id){
        int left = (id - 1 + NUM_OF_PHILOSOPHERS) % NUM_OF_PHILOSOPHERS;
        int right = (id + 1 + NUM_OF_PHILOSOPHERS) % NUM_OF_PHILOSOPHERS;
        forks[left]++;
        forks[right]++;

        notifyAll();
    }




    public static void main(String[] args) {

        Server server = new Server(4001);

        try (
                ServerSocket listener = new ServerSocket(server.port)
                ) {
            while(true) {
                Socket sock = listener.accept();

//                new RequestHandler(sock, server).start();

                server.pool.execute(new RequestHandler(sock, server));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}