I have a problem in my Java code that should simulate dining pholosophers problem, which is described here: http://en.wikipedia.org/wiki/Dining_philosophers_problem
I want to output the current state of all philosophers every time one of them eats or thinks. Output should look something like this:
"O X O o X (2)", where "X" means that philosopher eats, "O" means that he is thinking, and "o" means that he is waiting for chopsticks. The number in brackets indicates the number of the philosopher whose state has changed. The problem that I have is that only philosophers 1 and 3 (sometimes 2 and 4) eat, while others always think or wait for forks, and that repeats constantly, so the output looks like this:
O X O O O (2)
o X o X O (4)
o O o X o (2)
o O o O o (4)
o X o O o (2)
o X o X o (4)
o O o X o (2)
...
Complete code is here:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Stick{
boolean available;
public Stick(){
available = true;
}
public void setAvailability(boolean flag){
this.available = flag;
}
public boolean getAvailability(){
return available;
}
}
class Philosopher extends Thread{
private int id;
private Stick l, r;
private Lock monitor;
private Condition[] cond;
private Problem p;
private void outputState(int _id){
StringBuffer sb = new StringBuffer();
for(int i=0; i<5; i++)
sb.append(p.getState(i) + " ");
System.out.println(sb + "(" + (_id+1) + ")");
}
private void takeChopSticks(int _id) throws InterruptedException{
monitor.lock();
try{
p.setState(_id, "o");
while(!l.getAvailability() || !r.getAvailability()){
cond[_id].await();
}
l.setAvailability(false);
r.setAvailability(false);
p.setState(_id, "X");
outputState(_id);
}finally{
monitor.unlock();
}
}
private void eat() throws InterruptedException{
Thread.sleep(1000);
}
private void think(int _id) throws InterruptedException{
Thread.sleep(2000);
}
public void run(){
while(true){
try{
takeChopSticks(this.id);
eat();
releaseChopSticks(this.id);
think(this.id);
}catch(InterruptedException e){System.out.println("srusila se metoda run()");}
}
}
private void releaseChopSticks(int _id) throws InterruptedException{
monitor.lock();
try{
l.setAvailability(true);
r.setAvailability(true);
cond[_id].signalAll();
cond[(_id+4)%5].signalAll();
p.setState(_id, "O");
outputState(_id);
}finally{
monitor.unlock();
}
}
public Philosopher(Problem _p, int _id, Stick _l, Stick _r, Lock m){
cond = new Condition[5];
monitor = m;
id = _id;
l = _l;
r = _r;
p = _p;
for(int i=0; i<5; i++)
cond[i] = monitor.newCondition();
}
}
public class Problem {
Thread[] t;
Stick[] s;
private enum State {O, X, o};
private State[] state;
public State getState(int id){
return state[id];
}
public void setState(int id, String s){
if(s == "o")
state[id] = State.o;
else if(s=="O")
state[id] = State.O;
else if(s=="X")
state[id] = State.X;
}
public Problem(){
state = new State[5];
t = new Thread[5];
s = new Stick[5];
for(int i=0; i<5; i++){
s[i] = new Stick();
state[i] = State.O;
}
Lock m = new ReentrantLock();
for(int i=0; i<5; i++)
t[i] = new Philosopher(this, i, s[i], s[(i+4)%5], m);
for(int i=0; i<5; i++)
t[i].start();
}
public static void main(String[] args){
new Problem();
}
}
I know there are allready several questions about dining philosophers in Java, but none of them seem to help, and my code is a bit different. Thanks.
I've modified it quite a bit and it finally works.
The code is:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Chopstick{
private boolean availability;
public Chopstick(){
availability = true;
}
public boolean getAvailability(){
return availability;
}
public void setAvailability(boolean flag){
availability = flag;
}
}
class Helper{
private Lock mutex = null;
private Condition[] cond;
private String[] state;
private int[] id;
private void outputState(int id){
StringBuffer line = new StringBuffer();
for(int i=0; i<5; i++)
line.append(state[i] + " ");
System.out.println(line + "(" + (id+1) + ")");
}
public Helper(){
id = new int[5];
mutex = new ReentrantLock();
state = new String[5];
cond = new Condition[5];
for(int i=0; i<5; i++){
id[i] = i;
state[i] = "O";
cond[i] = mutex.newCondition();
}
}
public void setState(int id, String s){
state[id] = s;
}
public void grabChopsticks(int id, Chopstick l, Chopstick r){
mutex.lock();
try{
setState(id, "o");
while(!l.getAvailability() || !r.getAvailability())
cond[id].await();
l.setAvailability(false);
r.setAvailability(false);
setState(id, "X");
outputState(id);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
mutex.unlock();
}
}
public void releaseChopsticks(int id, Chopstick l, Chopstick r){
mutex.lock();
try{
setState(id, "O");
l.setAvailability(true);
r.setAvailability(true);
cond[(id+1)%5].signalAll();
cond[(id+4)%5].signalAll();
outputState(id);
}finally{
mutex.unlock();
}
}
}
class Philosopher implements Runnable{
private Helper hlp;
private Chopstick l, r;
private int id;
public Philosopher(int id, Chopstick l, Chopstick r, Helper i){
this.hlp = i;
this.l = l;
this.r = r;
this.id = id;
}
private void eat(){
try{
Thread.sleep(2000);
}catch(InterruptedException e){}
}
private void think(){
try{
Thread.sleep(2000);
}catch(InterruptedException e){}
}
public void run(){
while(true){
hlp.grabChopsticks(id, l, r);
eat();
hlp.releaseChopsticks(id, l, r);
think();
}
}
}
public class Problem {
private Chopstick[] s;
private Philosopher[] f;
private Helper hlp;
private void init(){
s = new Chopstick[5];
f = new Philosopher[5];
hlp = new Helper();
for(int i=0; i<5; i++)
s[i] = new Chopstick();
for(int i=0; i<5; i++){
f[i] = new Philosopher(i, s[i], s[(i+4)%5], hlp);
new Thread(f[i]).start();
}
}
public Problem(){
init();
}
public static void main(String[] args){
new Problem();
}
}
Related
I have a graph that contains objects of type GraphNodes. These nodes contain an object City that has properties if It's infected or not. I want to loop through all the nodes and check if a city is infected or not. I have a generic method getInfo which returns an object of type E in my case City. But when i try to chain another method or to get property i can't see them as if they are not available. All the classes in the code are from college so i can't add/remove methods. I've tried with foreach but I still can't get the methods.
Code:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.LinkedList;
class City {
String osnovna_granka;
boolean zarazen;
City(String osnovna_granka, boolean zarazen) {
this.osnovna_granka = osnovna_granka;
this.zarazen = zarazen;
}
#Override
public String toString() {
if (zarazen == true) {
return osnovna_granka + " zarazen";
} else {
return osnovna_granka + " nezarazen";
}
}
}
class Graph {
int num_nodes;
GraphNode<City> adjList[];
#SuppressWarnings("unchecked")
public Graph(int num_nodes) {
this.num_nodes = num_nodes;
adjList = (GraphNode<City>[]) new GraphNode[num_nodes];
}
int adjacent(int x, int y) {
// proveruva dali ima vrska od jazelot so
// indeks x do jazelot so indeks y
return (adjList[x].containsNeighbor(adjList[y])) ? 1 : 0;
}
void addEdge(int x, int y) {
// dodava vrska od jazelot so indeks x do jazelot so indeks y
if (!adjList[x].containsNeighbor(adjList[y])) {
adjList[x].addNeighbor(adjList[y]);
}
}
void deleteEdge(int x, int y) {
adjList[x].removeNeighbor(adjList[y]);
}
#Override
public String toString() {
String ret = new String();
for (int i = 0; i < this.num_nodes; i++) {
ret += i + ": " + adjList[i] + "\n";
}
return ret;
}
}
class GraphNode<E> {
private int index;//index (reden broj) na temeto vo grafot
private E info;
private LinkedList<GraphNode<E>> neighbors;
public GraphNode(int index, E info) {
this.index = index;
this.info = info;
neighbors = new LinkedList<GraphNode<E>>();
}
boolean containsNeighbor(GraphNode<E> o) {
return neighbors.contains(o);
}
void addNeighbor(GraphNode<E> o) {
neighbors.add(o);
}
void removeNeighbor(GraphNode<E> o) {
if (neighbors.contains(o)) {
neighbors.remove(o);
}
}
#Override
public String toString() {
String ret = "INFO:" + info + " SOSEDI:";
for (int i = 0; i < neighbors.size(); i++) {
ret += neighbors.get(i).info + " ";
}
return ret;
}
#Override
public boolean equals(Object obj) {
#SuppressWarnings("unchecked")
GraphNode<E> pom = (GraphNode<E>) obj;
return (pom.info.equals(this.info));
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public E getInfo() {
return info;
}
public void setInfo(E info) {
this.info = info;
}
public LinkedList<GraphNode<E>> getNeighbors() {
return neighbors;
}
public void setNeighbors(LinkedList<GraphNode<E>> neighbors) {
this.neighbors = neighbors;
}
}
public class Main {
public static void main(String[] args) throws Exception {
int i, j, k;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
Graph g = new Graph(N);
for (i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
st.nextToken();
String osnovna_granka = st.nextToken();
String str_zarazen = st.nextToken();
if (str_zarazen.equals("zarazen")) {
g.adjList[i] = new GraphNode(i, new City(osnovna_granka, true));
} else {
g.adjList[i] = new GraphNode(i, new City(osnovna_granka, false));
}
}
int M = Integer.parseInt(br.readLine());
for (i = 0; i < M; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
g.addEdge(a, b);
g.addEdge(b, a);
}
br.close();
Stack<GraphNode> stack = new Stack<>();
int counter = 0;
// vasiot kod ovde;
for(GraphNode gn: g.adjList) {
gn.getInfo().// Here the properties of City should show up
}
}
}
GraphNode is a generic type and you have not specified the type, the IDE cannot infer the type so no methods can be suggested. in the for loop you need to specify the type of the GraphNode.
for(GraphNode<City> gn: g.adjList)
The task is to write a program that creates and starts two threads ThreadFibonacci and ThreadOutput. ThreadFiobnacci should calculate the fibonacci numbers and put the results in its static public variable. ThreadOutput should output the fibonacci number and ThreadOutput has to be a daemon thread. You have to make the thread write out each fibonacci number only once. I do not know how to do that last part of the task.
You can only use sleep, interrupt, volatile and join.
Here is what I tried:
import java.util.Scanner;
public class Zadatak2{
public static void main(String[] args){
Scanner reader = new Scanner(System.in);
System.out.println("Enter a number: ");
int n = reader.nextInt();
Thread threadFibonaci = new Thread(new ThreadFibonaci(n));
Thread threadOutput = new ThreadOutput();
threadFibonaci.start();
threadOutput.start();
}
}
class ThreadFibonaci implements Runnable{
public static volatile long fn;
private int n;
public ThreadFibonaci(int n){
this.n = n;
}
public void run(){
long f0 = 0;
fn = f0;
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
long f1 = 1;
fn = f1;
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
for(int i=0; i<n; i++){
fn = f0 + f1;
f0 = f1;
f1 = fn;
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
class ThreadOutput extends Thread{
public ThreadOutput(){
setDaemon(true);
}
public void run(){
while(true){
System.out.println(ThreadFibonaci.fn);
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
You need top use one more volatile variable to store a flag whether current number was already printed or not
class ThreadFibonaci implements Runnable{
public static volatile long fn;
public static volatile boolean printed = false;
private int n;
public ThreadFibonaci(int n){
this.n = n;
}
public void run(){
long f0 = 0;
fn = f0;
while (!printed) {
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
long f1 = 1;
fn = f1;
printed = false;
while (!printed) {
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
for(int i=0; i<n; i++){
fn = f0 + f1;
f0 = f1;
f1 = fn;
printed = false;
while (!printed) {
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
class ThreadOutput extends Thread{
public ThreadOutput(){
setDaemon(true);
}
public void run(){
while(true){
while (ThreadFibonaci.printed) {
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
System.out.println(ThreadFibonaci.fn);
ThreadFibonaci.printed = true;
}
}
}
This uses a single volatile field to hold the value. when the value is 0 a new value can be published and when the value is negative, it acts as a poison pill, stopping the printing thread.
class A {
static volatile long value = 0;
static void publish(long x) {
while (value > 0) ;
value = x;
}
static long next() {
while (value == 0) ;
long ret = value;
if (ret > 0) value = 0;
return ret;
}
public static void main(String[] args) {
System.out.println("Enter a number: ");
int n = new java.util.Scanner(System.in).nextInt();
new Thread(() -> {
long a = 1; publish(a);
long b = 1; publish(b);
for (int i = 2; i < n; i++) {
long c = a + b; publish(c);
a = b; b = c;
}
publish(-1); // poison pill
}).start();
new Thread(() -> {
for (; ; ) {
long value = next();
if (value < 0) break;
System.out.println(value);
}
}).start();
}
}
I have the following code. I'm trying to do a breadth first search of a tree that I created call HabitItem.
Here is queue traveral
import java.io.File;
import java.util.*;
import java.util.concurrent.PriorityBlockingQueue;
public static void traverseQueue() {
queueHabitItems.add(head);
while(!queueHabitItems.isEmpty()){
HabitItem node = queueHabitItems.peek();
for(int i = 0; i < node.children.size(); i++)
{
HabitItem it = node.children.get(i);
System.out.print("node: ");
System.out.print(node.name);
System.out.print(", child: ");
System.out.println(it.name);
queueHabitItems.offer(it);
}
queueHabitItems.poll();
System.out.println("Something Good Is Coming");
}
}
I'm trying to implement a Queue. And I'm using the Poll() function to remove elements. Suppose I have the following Data in the Queue.
A B C D E
And I want to use poll() to remove the front element. Well for some reason, E goes to the front of the list, such that it becomes
E B C D
Am I doing something wrong or is there something that I don't fundamentally understand about Queues? Shouldn't B be the front item?
public class myMain {
static PriorityQueue<HabitItem> queueHabitItems = new PriorityQueue<HabitItem>();
static HabitItem head = new HabitItem("A");
static HabitItem B = new HabitItem("B");
static HabitItem C = new HabitItem("C");
static HabitItem D = new HabitItem("D");
static HabitItem E = new HabitItem("E");
static HabitItem F = new HabitItem("F");
static HabitItem G = new HabitItem("G");
static HabitItem H = new HabitItem("H");
static HabitItem I = new HabitItem("I");
static HabitItem J = new HabitItem("J");
static HabitItem K = new HabitItem("K");
static HabitItem L = new HabitItem("L");
static HabitItem M = new HabitItem("M");
static HabitItem N = new HabitItem("N");
static HabitItem O = new HabitItem("O");
public static void hardCodeHabits() {
System.out.print(D.id);
head.children.add(B);
head.children.add(C);
head.children.add(D);
head.children.add(E);
B.children.add(F);
B.children.add(G);
B.children.add(H);
C.children.add(I);
B.children.add(J);
E.children.add(K);
I.children.add(L);
L.children.add(N);
L.children.add(M);
N.children.add(O);
System.out.print(D.id);
}
public static void traverseQueue() {
queueHabitItems.add(head);
while(!queueHabitItems.isEmpty()){
HabitItem node = queueHabitItems.peek();
for(int i = 0; i < node.children.size(); i++)
{
HabitItem it = node.children.get(i);
System.out.print("node: ");
System.out.print(node.name);
System.out.print(", child: ");
System.out.println(it.name);
queueHabitItems.offer(it);
}
queueHabitItems.remove();
System.out.println("Something Good Is Coming");
}
}
public static void main(String[] args) {
System.out.println("Hello world");
hardCodeHabits();
traverseQueue();
try{
Scanner x = new Scanner(new File("justText.txt"));
Formatter y = new Formatter(new File("output.txt"));
y.format("%s", "hey");
y.close();
while (x.hasNext()) {
System.out.println(x.next());
}
}
catch(Exception e) {
System.out.println("Couldn't open the file!");
}
}
}
This is my HabitItems class
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class HabitItem implements Comparable<HabitItem> {
static int Counter = 0;
String name;
boolean completed[] = new boolean[7];
List<HabitItem> children = new ArrayList<HabitItem>();
int id;
public String getName(){
return name;
}
public boolean[] getCompleted(){
return completed;
}
public void setCompleted(int index, boolean checked){
completed[index] = checked;
}
public boolean isChecked(int index){
return completed[index];
}
public HabitItem(String name) {
super();
Counter++;
this.id = Counter;
this.name = name;
for(int i = 0; i < 7; i++){
completed[i] = false;
}
}
public HabitItem(int id) {
super();
Counter++;
this.id = id;
}
public int compareTo(HabitItem o) {
if(o.id == this.id)
{
return 1;
}
else
{
return 0;
}
}
}
Again, don't use peek, use remove:
while (!queueHabitItems.isEmpty()) {
//!! HabitItem node = queueHabitItems.peek();
HabitItem node = queueHabitItems.remove();
for (int i = 0; i < node.children.size(); i++) {
HabitItem it = node.children.get(i);
System.out.print("node: ");
System.out.print(node.name);
System.out.print(", child: ");
System.out.println(it.name);
queueHabitItems.offer(it);
}
// !! queueHabitItems.remove();
System.out.println("Something Good Is Coming");
}
The peek call just peeks into the collection but does not respect the priority. The poll and remove do respect this.
This is very old and probably doesn't matter anymore. But I will just say that it turned out that I was confused because I thought a priorityQueue was the exact same thing as a queue.
This is the class philosopher
public class Filosofo implements Runnable{
public String nome = null;
public static Bacchetta[] bacchette = new Bacchetta[5]; //this should be the resource
public Bacchetta bacchettaDX; //right resource
public Bacchetta bacchettaSX; //left resource
public static int indice = 0;
public int x[] = {};
public int y[] = {};
public JButton filosofo = new JButton(); //Button associated to the philos.
public Filosofo(String nome, int SX, int DX){
indice++;
for(int i = 0; i<5; i++){
bacchette[i] = new Bacchetta();
}
this.nome = nome;
this.bacchettaSX = bacchette[SX];
this.bacchettaDX = bacchette[DX];
}
#Override
public synchronized void run() {
Random r = new Random();
int random;
while(true){
random = (int) r.nextInt(100);
pensa(5000);
random = (int) r.nextInt(100);
mangia(5000);
}
}
//the method mangia means the phil. is eating, so has both chopsticks
public synchronized void mangia(int tempo){
do{
if(!bacchettaSX.isOccupied){
bacchettaSX.isOccupied = true;
bacchettaSX.setChiOccupa(this.nome);
}
if(!bacchettaDX.isOccupied){
bacchettaDX.isOccupied = true;
bacchettaDX.setChiOccupa(this.nome);
}
}while(bacchettaSX.getChiOccupa().compareTo(this.nome) != 0 && bacchettaDX.getChiOccupa().compareTo(this.nome) != 0);
this.filosofo.setBackground(Color.GREEN);
try {
sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(Filosofo.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("\t\t\t" + this.nome + " sta mangiando");
int a = 0;
/*for(long i = 0; i<1000000000; i++){
a++;
}*/
bacchettaSX.isOccupied = false;
bacchettaDX.isOccupied = false;
bacchettaSX.setChiOccupa(null);
bacchettaDX.setChiOccupa(null);
System.out.println("\t\t\t\t\t\t" + this.nome + " ha finito di mangiare");
this.filosofo.setBackground(Color.BLUE);
}
//the method pensa means the philosopher is no longer eating
public void pensa(int tempo){
System.out.println(this.nome + " sta ponderando");
try {
sleep(tempo);
} catch (InterruptedException ex) {
Logger.getLogger(Filosofo.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
It's supposed to print out in the terminal what's doing what, the problem is that they should eat one by one or in the best scenario maximum two philosophers. However, they eat all together. The synchronization is not doing what it's supposed to be doing. Where is the problem?
Your code block
for(int i = 0; i<5; i++){
bacchette[i] = new Bacchetta();
}
Initializes the static array each time you create a new philosopher, so they all end up with different bachettaSX and bachettaDX.
Initialize it once in a static code block outside of the constructor.
static {
for(int i = 0; i<5; i++){
bacchette[i] = new Bacchetta();
}
}
The code below is the classic Producer/Consumer problem.
The code runs fine, but is still very tedious to use. I need to implement an ArrayBlockingQueue, but I am unsure on how to do so in order for the program to become threadsafe.
Any help would be greatly appreciated.
import java.util.LinkedList;
import java.util.Queue;
public class ProducerConsumer{
private static int NUM_MESSAGES = 3;
private static int NUM_PRODUCERS = 5;
private static int NUM_CONSUMERS = 5;
public static void main(String[] args) throws InterruptedException{
Queue<String> buffer = new LinkedList<String>();
Thread[] producers = new Thread[NUM_PRODUCERS];
for(int i=0; i<NUM_PRODUCERS; i++){
producers[i] = new Producer("producer"+i, buffer);
producers[i].start();
}
Thread[] consumers = new Thread[NUM_CONSUMERS];
for(int i=0; i<NUM_CONSUMERS; i++){
consumers[i] = new Consumer("consumer"+i, buffer);
consumers[i].start();
}
for(int i=0; i<NUM_PRODUCERS; i++){
producers[i].join();
}
for(int i=0; i<NUM_CONSUMERS; i++){
consumers[i].join();
}
System.err.println("messages left in buffer:");
while(!buffer.isEmpty()){
System.err.println(buffer.remove());
}
}
public static class Producer extends Thread{
Queue<String> buffer;
public Producer(String name, Queue<String> newBuffer){
super(name);
buffer = newBuffer;
}
public void run(){
for (int i=0; i<NUM_MESSAGES; i++){
String message = "message "+i+" from thread "+getName();
buffer.add(message);
System.err.println("sent "+message);
try{
Thread.sleep((long)(Math.random()*10));
}catch(InterruptedException e){}
}
}
}
public static class Consumer extends Thread{
Queue<String> buffer;
public Consumer(String name, Queue<String> newBuffer){
super(name);
buffer = newBuffer;
}
public void run(){
int count = 0;
while (count < NUM_MESSAGES){
String message;
if(!buffer.isEmpty()){
message = buffer.remove();
System.err.println(getName()+" received "+message);
count++;
}
try{
Thread.sleep((long)(Math.random()*10));
}catch(InterruptedException e){}
}
}
}
}