КДП/Лаб 1 РТИ 2023 — разлика између измена
< КДП
Пређи на навигацију
Пређи на претрагу
(Dodata nova stranica) |
м (→2. задатак) |
||
| (Није приказано 7 међуизмена 6 корисника) | |||
| Ред 1: | Ред 1: | ||
{{tocright}} | {{tocright}} | ||
== Улазни тест (WIP) == | |||
=== 1. задатак === | |||
Да ли ће доћи до грешке при позиву obj.a() у следећем коду? | |||
<syntaxhighlight lang="java"> | |||
public class A { | |||
public synchronized void a() { | |||
//neki kod ... | |||
b(); | |||
} | |||
public void b() { | |||
//neki kod.. | |||
notifyAll(); | |||
} | |||
static A obj = new A(); | |||
} | |||
</syntaxhighlight> | |||
<div class="abc-list" data-solution="single"> | |||
# Да. | |||
# <span class="solution">Не.</span> | |||
</div> | |||
=== 2. задатак === | |||
Који од следећег су валидни начини да се иницијализује нит? | |||
<div class="abc-list" data-solution="multiple"> | |||
# <syntaxhighlight lang="java">Runnable r = new Runnable() { | |||
public void run(){ /*neki kod*/ } | |||
};</syntaxhighlight> | |||
# <syntaxhighlight lang="java" class="solution">Runnable r = new Runnable() { | |||
public void run(){ /*neki kod*/} | |||
}; | |||
Thread t = new Thread(r);</syntaxhighlight> | |||
# <syntaxhighlight lang="java" class="solution">Thread t = new Thread();</syntaxhighlight> | |||
# <syntaxhighlight lang="java" class="solution">public class Nit extends Thread { | |||
public void run(){ /*neki kod*/ } | |||
} | |||
Nit t = new Nit();</syntaxhighlight> | |||
# <syntaxhighlight lang="java" class="solution">Thread t = new Thread() { | |||
public void run(){ /*neki kod*/ } | |||
};</syntaxhighlight> | |||
</div> | |||
=== 3. задатак === | |||
Који од следећих су коректни начини да се употреби <code>Lock</code>? | |||
<div class="abc-list" data-solution="multiple"> | |||
# <syntaxhighlight lang="java" class="solution">public void criticalSection() { | |||
lock.lock(); | |||
try { | |||
//... | |||
} finally { | |||
lock.unlock(); | |||
} | |||
}</syntaxhighlight> | |||
# <syntaxhighlight lang="java">public synchronized void criticalSection() { | |||
lock.lock(); | |||
//... | |||
lock.unlock(); | |||
}</syntaxhighlight> | |||
# <syntaxhighlight lang="java">public void criticalSection() { | |||
lock.lock(); | |||
//... | |||
lock.unlock(); | |||
}</syntaxhighlight> | |||
# <syntaxhighlight lang="java">public synchronized void criticalSection() { | |||
lock.lock(); | |||
try { | |||
//... | |||
} finally { | |||
lock.unlock(); | |||
} | |||
}</syntaxhighlight> | |||
</div> | |||
== Поставка == | == Поставка == | ||
У зависности од групе било је потребно решити један од следећих проблема: | У зависности од групе било је потребно решити један од следећих проблема: | ||
1. Решити | 1. Решити <code>Unisex Bathroom</code> проблем користећи <code>ReentrantLock</code>. Потребно је да програм буде максимално конкурентан. | ||
2. Решити | 2. Решити <code>Atomic Broadcast</code> проблем користећи <code>AtomicInteger</code>. Потребно је да програм буде максимално конкурентан. | ||
== Решење == | == Решење за Unisex Bathroom == | ||
Испод је решење за Unisex Bathroom. | Испод је решење за Unisex Bathroom. | ||
| Ред 235: | Ред 317: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Решење за AtomicInteger == | |||
Испод је решење за Atomic Broadcast са једноелементним бафером. | |||
==== <code>Consumer.java</code> ==== | |||
<syntaxhighlight lang="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); | |||
} | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
==== <code>Producer.java</code> ==== | |||
<syntaxhighlight lang="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); | |||
} | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
Код за тестирање функционалности: | |||
==== <code>Test.java</code> ==== | |||
<syntaxhighlight lang="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(); | |||
} | |||
} | |||
</syntaxhighlight> | |||
[[Категорија:КДП]] | |||
[[Категорија:Лабораторијске вежбе]] | |||
Тренутна верзија на датум 28. април 2024. у 23:35
Улазни тест (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();
}
}