КДП/Лаб 1 РТИ 2023
< КДП
Пређи на навигацију
Пређи на претрагу
Улазни тест (WIP)
1. задатак
Да ли ће доћи до грешке при позиву obj.a() у следећем коду?
public class A {
public synchronized void a() {
//neki kod ...
b();
}
public void b() {
//neki kod..
notifyAll();
}
static A obj = new A();
}
- Да.
- Не.
2. задатак
Који од следећег су валидни начини да се иницијализује нит?
Runnable r = new Runnable() { public void run(){ /*neki kod*/ } };
Runnable r = new Runnable() { public void run(){ /*neki kod*/} }; Thread t = new Thread(r);
Thread t = new Thread();
public class Nit extends Thread { public void run(){ /*neki kod*/ } } Nit t = new Nit();
Thread t = new Thread() { public void run(){ /*neki kod*/ } };
3. задатак
Који од следећих су коректни начини да се употреби Lock
?
public void criticalSection() { lock.lock(); try { //... } finally { lock.unlock(); } }
public synchronized void criticalSection() { lock.lock(); //... lock.unlock(); }
public void criticalSection() { lock.lock(); //... lock.unlock(); }
public synchronized void criticalSection() { lock.lock(); try { //... } finally { lock.unlock(); } }
Поставка
У зависности од групе било је потребно решити један од следећих проблема:
1. Решити Unisex Bathroom
проблем користећи ReentrantLock
. Потребно је да програм буде максимално конкурентан.
2. Решити Atomic Broadcast
проблем користећи AtomicInteger
. Потребно је да програм буде максимално конкурентан.
Решење за Unisex Bathroom
Испод је решење за Unisex Bathroom.
Test.java
package UnisexBathLocksLab1PrvaGrupa;
public class Test {
public static void main(String[] args) {
int m = 5;
int w = 5;
int N = 4;
Bathroom b = new Bathroom(N);
Thread mt[] = new Thread[m];
Thread wt[] = new Thread[m];
for(int i = 0; i < m; i++) {
mt[i] = new Man(b);
mt[i].start();
}
for(int i = 0; i < w; i++) {
wt[i] = new Woman(b);
wt[i].start();
}
}
}
Woman.java
package UnisexBathLocksLab1PrvaGrupa;
public class Woman extends Thread{
public int id;
public static int running_id = 0;
Bathroom bath;
public Woman(Bathroom bath) {
id = running_id++;
this.bath = bath;
}
@Override
public void run() {
while(true) {
bath.w_enter(id);
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
bath.w_exit(id);
}
}
}
Man.java
package UnisexBathLocksLab1PrvaGrupa;
public class Man extends Thread{
public int id;
public static int running_id = 0;
Bathroom bath;
public Man(Bathroom bath) {
id = running_id++;
this.bath = bath;
}
@Override
public void run() {
while(true) {
bath.m_enter(id);
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
bath.m_exit(id);
}
}
}
Bathroom.java
package UnisexBathLocksLab1PrvaGrupa;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Bathroom {
private int woman_cnt = 0;
private int man_cnt = 0;
private int capacity = 0;
Lock lock = new ReentrantLock();
Condition all = lock.newCondition();
private int ticket = 0;
private int next = 0;
public Bathroom(int N) {
this.ticket = 0;
this.next = 0;
this.man_cnt = 0;
this.woman_cnt = 0;
this.capacity = N;
}
public void m_enter(int id) {
lock.lock();
try {
int my_ticket = ticket++;
System.out.println("Man(" + id + ") waiting");
while (my_ticket != next || woman_cnt > 0 || man_cnt >= capacity) {
all.awaitUninterruptibly();
}
System.out.println("Man(" + id + ") entered");
man_cnt += 1;
this.next += 1;
} finally {
lock.unlock();
}
}
public void m_exit(int id) {
lock.lock();
try {
System.out.println("Man(" + id + ") left");
man_cnt -= 1;
all.signalAll();
} finally {
lock.unlock();
}
}
public void w_enter(int id) {
lock.lock();
try {
int my_ticket = ticket++;
System.out.println("Woman(" + id + ") waiting");
while (my_ticket != next || man_cnt > 0 || woman_cnt >= capacity) {
all.awaitUninterruptibly();
}
System.out.println("Woman(" + id + ") entered");
woman_cnt += 1;
next += 1;
} finally {
lock.unlock();
}
}
public void w_exit(int id) {
lock.lock();
try {
System.out.println("Woman(" + id + ") left");
woman_cnt -= 1;
all.signalAll();
} finally {
lock.unlock();
}
}
}
Решење за AtomicInteger
Испод је решење за Atomic Broadcast са једноелементним бафером.
Consumer.java
import java.util.concurrent.atomic.AtomicInteger;
public class Consumer extends Thread {
private static int static_id = 0;
private AtomicInteger buffer;
private AtomicInteger[] read_count;
private int id;
public Consumer(AtomicInteger buffer, AtomicInteger[] read_count) {
this.buffer = buffer;
this.read_count = read_count;
this.id = static_id++;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
while (read_count[id].get() == 1) {
Thread.onSpinWait();
}
int element = buffer.get();
System.out.println("Consumer " + id + " read element " + element);
read_count[id].set(1);
try {
Thread.sleep((int) (Math.random() * 2000));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
Producer.java
import java.util.concurrent.atomic.AtomicInteger;
public class Producer extends Thread {
private final int consumer_count;
private AtomicInteger buffer;
private AtomicInteger[] read_count;
public Producer(AtomicInteger buffer, AtomicInteger[] read_count, int consumer_count) {
this.buffer = buffer;
this.read_count = read_count;
this.consumer_count = consumer_count;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < consumer_count; j++) {
while(read_count[j].get() == 0)
Thread.onSpinWait();
}
int random_element = (int) (Math.random() * 10);
System.out.println("Producer produced element: "+random_element);
buffer.set(random_element);
for (int j = 0; j < consumer_count; j++) {
read_count[j].set(0);
}
}
}
}
Код за тестирање функционалности:
Test.java
import java.util.concurrent.atomic.AtomicInteger;
public class Test {
private static final int CONSUMER_COUNT = 10;
public static void main(String[] args) {
AtomicInteger[] read_count = new AtomicInteger[CONSUMER_COUNT];
AtomicInteger buffer = new AtomicInteger(0);
Consumer[] consumers = new Consumer[CONSUMER_COUNT];
Producer producer = new Producer(buffer, read_count, CONSUMER_COUNT);
for (int i = 0; i < CONSUMER_COUNT; i++) {
read_count[i] = new AtomicInteger(1);
consumers[i] = new Consumer(buffer, read_count);
consumers[i].start();
}
producer.start();
}
}