Concurrency
class Foo {
private int counter = 1;
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
synchronized (this) {
while (counter != 1) {
this.wait();
}
printFirst.run();
counter = 2;
this.notifyAll();
}
// printFirst.run() outputs "first". Do not change or remove this line.
}
public void second(Runnable printSecond) throws InterruptedException {
synchronized (this) {
while (counter != 2) {
this.wait();
}
printSecond.run();
counter = 3;
this.notifyAll();
}
// printSecond.run() outputs "second". Do not change or remove this line.
// printSecond.run();
}
public void third(Runnable printThird) throws InterruptedException {
synchronized (this) {
while (counter != 3) {
this.wait();
}
printThird.run();
counter = 1;
this.notifyAll();
}
}
}
Deque<Integer> d;
int size;
Object lock;
public BoundedBlockingQueue(int capacity) {
d = new LinkedList<>();
size = capacity;
lock = new Object();
}
public void enqueue(int element) throws InterruptedException {
synchronized (lock) {
while (d.size() == size) {
lock.wait();
}
d.addLast(element);
lock.notify();
}
}
public int dequeue() throws InterruptedException {
int val = 0;
synchronized (lock) {
while (d.isEmpty()) lock.wait();
val = d.removeFirst();
lock.notify();
}
return val;
}
public int size() {
return d.size();
}
class FooBar {
private int n;
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private volatile boolean fooTurn = true;
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
lock.lock();
try {
while (!fooTurn) {
condition.await();
}
printFoo.run();
condition.signalAll();
fooTurn = false;
} finally {
lock.unlock();
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
lock.lock();
try {
while (fooTurn) {
condition.await();
}
printBar.run();
condition.signalAll();
fooTurn = true;
} finally {
lock.unlock();
}
}
}
}
Web Crawler with future
import java.util.*;
import java.util.concurrent.*;
public interface WebsiteScanner {
/**
* Makes a call-out to the webpage and scrapes the HTML
* for any hyperlinks to other URLs present in the webpage.
*
* @param url The URL of the webpage to scrape
* @return A list of URLs (as strings) that are directly linked from the given webpage
*/
List<String> getLinks(String url);
}
class Solution {
/**
* Finds the minimum number of hops required to navigate from webpageStart to webpageEnd.
*
* @param webpageStart The starting webpage URL
* @param webpageEnd The target webpage URL
* @param maxHops The maximum number of hops allowed
* @param scanner WebsiteScanner instance to fetch links
* @return The minimum number of hops, or -1 if not reachable within maxHops
*/
public static int findMinimumHops(String webpageStart, String webpageEnd, int maxHops, WebsiteScanner scanner) {
Set<String> visited = ConcurrentHashMap.newKeySet();
Queue<String> queue = new LinkedList<>();
ExecutorService executor = Executors.newFixedThreadPool(10);
queue.offer(webpageStart);
visited.add(webpageStart);
int level = 0;
while (!queue.isEmpty()) {
int size = queue.size();
List<Future<List<String>>> futures = new ArrayList<>();
for (int i = 0; i < size; i++) {
String current = queue.poll();
if (current.equals(webpageEnd)) {
executor.shutdown();
return level;
}
futures.add(executor.submit(() -> scanner.getLinks(current)));
}
for (Future<List<String>> future : futures) {
try {
for (String next : future.get()) {
if (visited.add(next)) {
queue.offer(next);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (++level > maxHops) {
executor.shutdown();
return -1;
}
}
executor.shutdown();
return -1;
}
}
Last updated
Was this helpful?