Is there some neat way to make Threads (in Java) wait for theoretical time units as opposed to using Thread.sleep()?

Viewed 43

Currently working on a university assessment, so I won't share specifics and I'm not asking for any explanation that will help me solve the main problem. I've already solved the problem, but my solution might be considered a little messy.

Basically, we're working with concurrency and semaphores. There is some shared resource that up to X (where X > 1) number of threads can access at a time and an algorithm which makes it a little more complicated than just acquiring and releasing access. Threads come at a certain time, use the resource for a certain time and then leave. We are to assume that no time is wasted when arriving, accessing, releasing and leaving the resource. The goal is to demonstrate that the algorithm we have written works by outputting the times a thread arrives, accesses the resource and leaves for each thread.

I'm using a semaphore with X number of permits to govern access. And it's all working fine, but I think the way I arrive at the expected output might be a bit janky. Here's something like what I have currently:

@Override
public void run() {
    long alive = System.currentTimeMillis();
    try { Thread.sleep(arrivalTime * 1000); }
    catch (InterruptedException e) {} // no interrupts implemented
    long actualArriveTime = System.currentTimeMillis() - alive;

    boolean accessed = false;
    while (!accessed) accessed = tryAcquire();
    long actualAccessTime = System.currentTimeMillis() - alive;

    try { Thread.sleep(useTime * 1000); }
    catch (InterruptedException e) {} // no interrupts implemented
    release();
    long actualDepartTime = System.currentTimeMillis() - alive;

    System.out.println(actualArriveTime);
    System.out.println(actualAccessTime);
    System.out.println(actualDepartTime);
}

I do it this way because where the expected output might be:

Thread  Arrival Access  Departure
A       0       0       3
B       0       0       5
C       2       2       6
...     ...     ...     ...

My output looks something like:

Thread  Arrival Access  Departure
A       0       0       3006
B       0       0       5008
C       2       2       6012
...     ...     ...     ...

I'm essentially making the time period much larger so that if the computer takes a fews milliseconds to acquire(), for example, it doesn't affect the number much. Then I can round to the nearest second to get the expected output. My algorithm works, but there are issues with this. A: It's slow; B: With enough threads, the milliseconds of delay may build so that I round to the wrong number.

I need something more like this:

public static void main(String[] args) {
    int clock = 0;
    while (threadsWaiting) {
        clock++;
    }
}

@Override
public void run() {
    Thread.waitUntil(clock == arrivalTime);

    boolean accessed = false;
    while (!accessed) accessed = tryAcquire();
    int accessTime = clock;

    int depatureTime = accessTime + useTime;
    Thread.waitUntil(clock == departureTime);
    release();

    System.out.println(arrivalTime);
    System.out.println(accessTime);
    System.out.println(departureTime);
}

Hopefully that's clear. Any help is appreciated. Thanks!

0 Answers
Related