My Five Philosophers are all eating at the same time, why? - java

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();
}
}

Related

How to print fibonacci number, multithreading?

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();
}
}

Thread put in TextArea JavaFX

I know how to display text from thread in console, but how can I put it in TextArea? Also since my text is chars and numbers, how can I convert them to string since TextArea takes only String if I am right?
I need to append PrintNum, LetterSmall and LetterBig in TextArea.
Does someone know the way? Any help would be appreciated!
public class pracice extends Application {
#Override
public void start(Stage primaryStage) {
TextArea ta = new TextArea();
Button btn = new Button();
btn.setText("Show");
btn.setOnAction(new EventHandler<ActionEvent>() {
Runnable run = new PrintNum(25);
Thread th1 = new Thread(run);
char lett;
char lettUp;
Runnable let = new LetterSmall(lett);
Thread th2 = new Thread(let);
Runnable lUp = new LetterBig(lettUp);
Thread th3 = new Thread(lUp);
#Override
public void handle(ActionEvent event) {
System.out.append("\nBegin\n");
th1.start();
try{
th1.join(2000);
} catch (InterruptedException e){
e.printStackTrace();
}
th2.start();
try{
th2.join();
} catch (InterruptedException e){
e.printStackTrace();
}
th3.start();
}
});
BorderPane root = new BorderPane();
root.setTop(btn);
root.setCenter(ta);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Practice");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class PrintNum implements Runnable {
private int lastNum;
Random r = new Random();
public PrintNum(int n){
lastNum = n;
}
public void run(){
System.out.append("\n");
for(int i = 1; i <= lastNum; i++){
int rN = r.nextInt(25) + 1;
System.out.append((lastNum - rN) + " ");
}
}
}
class LetterSmall implements Runnable {
Random r = new Random();
private char lett;
public LetterSmall(char s){
lett = s;
}
public void run(){
System.out.append("\n");
for(int i = 1; i <= 25; i++){
char c = (char) (r.nextInt(26) + 'a');
lett = c;
System.out.append(lett + " ");
}
}
}
class LetterBig implements Runnable {
Random r = new Random();
private char lettUp;
public LetterBig(char up){
lettUp = up;
}
public void run(){
System.out.append("\n");
for(int i = 1; i <= 25; i++){
char c = (char) (r.nextInt(26) + 'A');
lettUp = c;
System.out.append(lettUp + " ");
}
}
}
So I found a solution for TextArea input. Instead of making three class threads, I moved them inside the primary JavaFX class. Thanks everyone for help.
It looks like this:
new Thread(new Runnable() {
private int lastNum = 25;
private char lett;
private char lettUp;
Random r = new Random();
#Override
public void run() {
Thread th1 = new Thread();
ta.appendText("\n");
for(int i = 1; i <= lastNum; i++){
int rN = r.nextInt(25) + 1;
ta.appendText((lastNum - rN) + " ");
}
Thread th2 = new Thread();
ta.appendText("\n\n");
for(int i = 1; i <= 25; i++){
char c = (char) (r.nextInt(26) + 'a');
lett = c;
ta.appendText(lett + " ");
}
Thread th3 = new Thread();
ta.appendText("\n\n");
for(int i = 1; i <= 25; i++){
char c = (char) (r.nextInt(26) + 'A');
lettUp = c;
ta.appendText(lettUp + " ");
}
th1.start();
try{
th1.join(2000);
} catch (InterruptedException e){
e.printStackTrace();
}
th2.start();
try{
th1.join();
} catch (InterruptedException e){
e.printStackTrace();
}
th3.start();
try{
th1.join();
th2.join();
th3.join();
} catch (InterruptedException e){
e.printStackTrace();
}
}
}).start();

Design Pattern - Which Design Pattern to use in this case

I've created a Dataset class used to store and manipulate a dataset. A different class, called Dataset Iris, extends Dataset because Dataset is Principal class where every different datasets (iris and so on) extends it because they have a their feature and a different methods to load it(I can load from a file .txt, .data or database and so on...).
My actually code is this and run, but my teacher tells to me that I should apply "Decorator" design pattern to solve it, but looking the Decorator UML I don't think it because I haven't the "Concrete component" (I can create . What do you think about it? Is a Decorator design pattern or other (like template methods)?
Dataset
public class Dataset
{
private int nFeature;
private int nRecord;
private ArrayList<Integer> featureUsed;
private String nomeDataset;
//public double Mat [][];
private ArrayList<ArrayList<Double>> Mat;
public double Distanza(int i, ArrayList<Double> centroide)
{
double Sum=0;
for(int j=0; j<nFeature; j++)
Sum+=Math.pow((centroide.get(j) - Mat.get(j).get(i)), 2);
return Math.sqrt(Sum);
}
public double getCell(int i, int j)
{
return Mat.get(j).get(i);
}
public void initMat()
{
Mat = new ArrayList<ArrayList<Double>>();
featureUsed = new ArrayList<Integer>();
for(int i=0; i< nFeature; i++)
{
Mat.add(new ArrayList<Double>());
featureUsed.add(i);
}
}
public void writeDataset()
{
for(int i=0; i< nRecord; i++)
{
for(int j=0; j < nFeature; j++)
{
System.out.print( Mat.get(j).get(i)+ " ");
}
System.out.println("\n");
}
}
public ArrayList<Double> getRecord(int i_r)
{
ArrayList<Double> record = new ArrayList<Double>();
for(int i=0; i<nFeature; i++)
record.add( Mat.get(i).get(i_r));
return record;
}
public Dataset(int nFeature, String Nome)
{
setnFeature(4);
setNomeDataset(Nome);
initMat();
}
public Dataset(ArrayList<ArrayList<Double>> MatInput, ArrayList<Integer> featureSelected, int nRecord)
{
Mat = new ArrayList<ArrayList<Double>>();
this.featureUsate = new ArrayList<Integer>(featureSelected);
this.nRecord = nRecord;
this.setnFeature(featureSelected.size());
for(int i=0; i<featureSelected.size(); i++)
setCol( MatInput.get( featureSelected.get(i)));
}
public Dataset() {
// TODO Auto-generated constructor stub
}
public void setCol( ArrayList<Double> colVal)
{
this.Mat.add(colVal);
}
public ArrayList<ArrayList<Double>> getMat()
{
return this.Mat;
}
public int getnFeature() {
return this.nFeature;
}
public int getnRecord() {
return this.nRecord;
}
public void setnFeature(int nFeature)
{
this.nFeature = nFeature;
return;
}
public void setnRecord(int nRecord) {
this.nRecord=nRecord;
return;
}
public void setTable(int Colonna, Double Valore)
{
Mat.get(Colonna).add(Valore);
}
public String getNomeDataset() {
return this.nomeDataset;
}
public void setNomeDataset(String nomeDataset) {
this.nomeDataset = new String(nomeDataset);
}
public double[][] toMatrix()
{
double[][] matrix = new double[this.getnRecord()][this.getnFeature()];
for(int i=0; i< nRecord; i++)
{
for(int j=0; j < nFeature; j++)
{
matrix[i][j] = Mat.get(j).get(i);
}
}
return matrix;
}
public ArrayList<Integer> getFeatureUsed()
{return this.featureUsed;}
}
DatasetIris
public class DatasetIris extends Dataset
{
private String[] nomiFeature = {"Petal Length",
"Petal Width",
"Sepal Length",
"Sepal Width"
};
public DatasetIris(String NomeFile) throws IOException
{
super(4,NomeFile);
super.setnRecord( CaricaDataset(NomeFile) );
}
// Other DatasetIris with their load (database or other type of files)?
protected int loadDataset(String pathFile) throws IOException
{
int iRecord = 0;
BufferedReader bufferLetto = null;
String line = "";
String cvsSplitBy = ",";
try {
bufferLetto = new BufferedReader(new FileReader(pathFile));
while ((line = bufferLetto.readLine()) != null)
{
if (line.length() > 0)
{
String[] cell = line.split(cvsSplitBy);
this.addRow(cell);
iRecord++;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferLetto != null) {
try {
bufferLetto.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return iRecord;
}
// New File.data to Mat
public void addRow(Object cell[])
{
for(int i=0; i<getnFeature(); i++)
super.setTable(i, Double.parseDouble(cell[i].toString()));
}
}

Painting canvas and System.out.println() not working

I have JFrame with a start button, which triggers the calculation of a Julia Set.
The code that is executed when the start button is clicked is as follows:
public void actionPerformed(ActionEvent aActionEvent)
{
String strCmd = aActionEvent.getActionCommand();
if (strCmd.equals("Start"))
{
m_cCanvas.init();
m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
m_bRunning = true;
this.handleCalculation();
}
else if (aActionEvent.getSource() == m_cTReal)
Which used to work fine, except that the application could not be closed anymore. So I tried to use m_bRunning in a separate method so that actionPerformed() isn't blocked all the time to see if that would help, and then set m_bRunning = false in the method stop() which is called when the window is closed:
public void run()
{
if(m_bRunning)
{
this.handleCalculation();
}
}
The method run() is called from the main class in a while(true) loop.
Yet unfortunately, neither did that solve the problem, nor do I now have any output to the canvas or any debug traces with System.out.println(). Could anyone point me in the right direction on this?
EDIT:
Here are the whole files:
// cMain.java
package juliaSet;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.Dimension;
public class cMain {
public static void main(String[] args)
{
int windowWidth = 1000;//(int)screenSize.getWidth() - 200;
int windowHeight = 800;//(int)screenSize.getHeight() - 50;
int plotWidth = 400;//(int)screenSize.getWidth() - 600;
int plotHeight = 400;//(int)screenSize.getHeight() - 150;
JuliaSet cJuliaSet = new JuliaSet("Julia Set", windowWidth, windowHeight, plotWidth, plotHeight);
cJuliaSet.setVisible(true);
while(true)
{
cJuliaSet.run();
}
}
}
// JuliaSet.java
package juliaSet;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.Random;
import java.io.*;
import java.lang.ref.*;
public class JuliaSet extends JFrame implements ActionListener
{
private JButton m_cBStart;
private JTextField m_cTReal;
private JTextField m_cTImag;
private JTextField m_cTDivergThresh;
private JLabel m_cLReal;
private JLabel m_cLImag;
private JLabel m_cLDivergThresh;
private int m_iDivergThresh = 10;
private String m_cMsgDivThresh = "Divergence threshold = " + m_iDivergThresh;
private JuliaCanvas m_cCanvas;
private int m_iPlotWidth; // number of cells
private int m_iPlotHeight; // number of cells
private Boolean m_bRunning = false;
private double m_dReal = 0.3;
private double m_dImag = -0.5;
private String m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
private String m_cMsgIter = "x = 0, y = 0";
private Complex m_cCoordPlane[][];
private double m_dAbsSqValues[][];
private int m_iIterations[][];
private Complex m_cSummand;
private BufferedImage m_cBackGroundImage = null;
private FileWriter m_cFileWriter;
private BufferedWriter m_cBufferedWriter;
private String m_sFileName = "log.txt";
private Boolean m_bWriteLog = false;
private static final double PLOTMAX = 2.0; // we'll have symmetric axes
// ((0,0) at the centre of the
// plot
private static final int MAXITER = 0xff;
JuliaSet(String aTitle, int aFrameWidth, int aFrameHeight, int aPlotWidth, int aPlotHeight)
{
super(aTitle);
this.setSize(aFrameWidth, aFrameHeight);
m_iPlotWidth = aPlotWidth;
m_iPlotHeight = aPlotHeight;
m_cSummand = new Complex(m_dReal, m_dImag);
m_cBackGroundImage = new BufferedImage(aFrameWidth, aFrameHeight, BufferedImage.TYPE_INT_RGB);
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
stop();
super.windowClosing(e);
System.exit(0);
}
});
GridBagLayout cLayout = new GridBagLayout();
GridBagConstraints cConstraints = new GridBagConstraints();
this.setLayout(cLayout);
m_cCanvas = new JuliaCanvas(m_iPlotWidth, m_iPlotHeight);
m_cCanvas.setSize(m_iPlotWidth, m_iPlotHeight);
m_cBStart = new JButton("Start");
m_cBStart.addActionListener(this);
m_cTReal = new JTextField(5);
m_cTReal.addActionListener(this);
m_cTImag = new JTextField(5);
m_cTImag.addActionListener(this);
m_cTDivergThresh = new JTextField(5);
m_cTDivergThresh.addActionListener(this);
m_cLReal = new JLabel("Re(c):");
m_cLImag = new JLabel("Im(c):");
m_cLDivergThresh = new JLabel("Divergence Threshold:");
cConstraints.insets.top = 3;
cConstraints.insets.bottom = 3;
cConstraints.insets.right = 3;
cConstraints.insets.left = 3;
// cCanvas
cConstraints.gridx = 0;
cConstraints.gridy = 0;
cLayout.setConstraints(m_cCanvas, cConstraints);
this.add(m_cCanvas);
// m_cLReal
cConstraints.gridx = 0;
cConstraints.gridy = 1;
cLayout.setConstraints(m_cLReal, cConstraints);
this.add(m_cLReal);
// m_cTReal
cConstraints.gridx = 1;
cConstraints.gridy = 1;
cLayout.setConstraints(m_cTReal, cConstraints);
this.add(m_cTReal);
// m_cLImag
cConstraints.gridx = 0;
cConstraints.gridy = 2;
cLayout.setConstraints(m_cLImag, cConstraints);
this.add(m_cLImag);
// m_cTImag
cConstraints.gridx = 1;
cConstraints.gridy = 2;
cLayout.setConstraints(m_cTImag, cConstraints);
this.add(m_cTImag);
// m_cLDivergThresh
cConstraints.gridx = 0;
cConstraints.gridy = 3;
cLayout.setConstraints(m_cLDivergThresh, cConstraints);
this.add(m_cLDivergThresh);
// m_cTDivergThresh
cConstraints.gridx = 1;
cConstraints.gridy = 3;
cLayout.setConstraints(m_cTDivergThresh, cConstraints);
this.add(m_cTDivergThresh);
// m_cBStart
cConstraints.gridx = 0;
cConstraints.gridy = 4;
cLayout.setConstraints(m_cBStart, cConstraints);
this.add(m_cBStart);
if (m_bWriteLog)
{
try
{
m_cFileWriter = new FileWriter(m_sFileName, false);
m_cBufferedWriter = new BufferedWriter(m_cFileWriter);
} catch (IOException ex) {
System.out.println("Error opening file '" + m_sFileName + "'");
}
}
this.repaint();
this.transformCoordinates();
}
public synchronized void stop()
{
if (m_bRunning)
{
m_bRunning = false;
boolean bRetry = true;
}
if (m_bWriteLog)
{
try {
m_cBufferedWriter.close();
m_cFileWriter.close();
} catch (IOException ex) {
System.out.println("Error closing file '" + m_sFileName + "'");
}
}
}
public void collectGarbage()
{
Object cObj = new Object();
WeakReference ref = new WeakReference<Object>(cObj);
cObj = null;
while(ref.get() != null) {
System.gc();
}
}
public void setSummand(Complex aSummand)
{
m_cSummand.setIm(aSummand.getIm());
m_dImag = aSummand.getIm();
m_cSummand.setRe(aSummand.getRe());
m_dReal = aSummand.getRe();
m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
}
public void paint(Graphics aGraphics)
{
Graphics cScreenGraphics = aGraphics;
// render on background image
aGraphics = m_cBackGroundImage.getGraphics();
this.paintComponents(aGraphics);
// drawString() calls are debug code only....
aGraphics.setColor(Color.BLACK);
aGraphics.drawString(m_cSMsg, 10, 450);
aGraphics.drawString(m_cMsgIter, 10, 465);
aGraphics.drawString(m_cMsgDivThresh, 10, 480);
// rendering is done, draw background image to on screen graphics
cScreenGraphics.drawImage(m_cBackGroundImage, 0, 0, null);
}
public void actionPerformed(ActionEvent aActionEvent)
{
String strCmd = aActionEvent.getActionCommand();
if (strCmd.equals("Start"))
{
m_cCanvas.init();
m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
m_bRunning = true;
}
else if (aActionEvent.getSource() == m_cTReal)
{
m_dReal = Double.parseDouble(m_cTReal.getText());
m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
m_cSummand.setRe(m_dReal);
}
else if (aActionEvent.getSource() == m_cTImag)
{
m_dImag = Double.parseDouble(m_cTImag.getText());
m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
m_cSummand.setIm(m_dImag);
}
else if (aActionEvent.getSource() == m_cTDivergThresh)
{
m_iDivergThresh = Integer.parseInt(m_cTDivergThresh.getText());
m_cMsgDivThresh = "Divergence threshold = " + m_iDivergThresh;
}
this.update(this.getGraphics());
}
public void transformCoordinates()
{
double dCanvasHeight = (double) m_cCanvas.getHeight();
double dCanvasWidth = (double) m_cCanvas.getWidth();
// init matrix with same amount of elements as pixels in canvas
m_cCoordPlane = new Complex[(int) dCanvasHeight][(int) dCanvasWidth];
double iPlotRange = 2 * PLOTMAX;
for (int i = 0; i < dCanvasHeight; i++)
{
for (int j = 0; j < dCanvasWidth; j++)
{
m_cCoordPlane[i][j] = new Complex((i - (dCanvasWidth / 2)) * iPlotRange / dCanvasWidth,
(j - (dCanvasHeight / 2)) * iPlotRange / dCanvasHeight);
}
}
}
public void calcAbsSqValues()
{
int iCanvasHeight = m_cCanvas.getHeight();
int iCanvasWidth = m_cCanvas.getWidth();
// init matrix with same amount of elements as pixels in canvas
m_dAbsSqValues = new double[iCanvasHeight][iCanvasWidth];
m_iIterations = new int[iCanvasHeight][iCanvasWidth];
Complex cSum = new Complex();
if (m_bWriteLog) {
try
{
m_cBufferedWriter.write("m_iIterations[][] =");
m_cBufferedWriter.newLine();
}
catch (IOException ex)
{
System.out.println("Error opening file '" + m_sFileName + "'");
}
}
for (int i = 0; i < iCanvasHeight; i++)
{
for (int j = 0; j < iCanvasWidth; j++)
{
cSum.setRe(m_cCoordPlane[i][j].getRe());
cSum.setIm(m_cCoordPlane[i][j].getIm());
m_iIterations[i][j] = 0;
do
{
m_iIterations[i][j]++;
cSum.square();
cSum.add(m_cSummand);
m_dAbsSqValues[i][j] = cSum.getAbsSq();
} while ((m_iIterations[i][j] < MAXITER) && (m_dAbsSqValues[i][j] < m_iDivergThresh));
this.calcColour(i, j, m_iIterations[i][j]);
m_cMsgIter = "x = " + i + " , y = " + j;
if(m_bWriteLog)
{
System.out.println(m_cMsgIter);
System.out.flush();
}
if (m_bWriteLog) {
try
{
m_cBufferedWriter.write(Integer.toString(m_iIterations[i][j]));
m_cBufferedWriter.write(" ");
}
catch (IOException ex) {
System.out.println("Error writing to file '" + m_sFileName + "'");
}
}
}
if (m_bWriteLog) {
try
{
m_cBufferedWriter.newLine();
}
catch (IOException ex) {
System.out.println("Error writing to file '" + m_sFileName + "'");
}
}
}
m_dAbsSqValues = null;
m_iIterations = null;
cSum = null;
}
private void calcColour(int i, int j, int aIterations)
{
Color cColour = Color.getHSBColor((int) Math.pow(aIterations, 4), 0xff,
0xff * ((aIterations < MAXITER) ? 1 : 0));
m_cCanvas.setPixelColour(i, j, cColour);
cColour = null;
}
private void handleCalculation()
{
Complex cSummand = new Complex();
for(int i = -800; i <= 800; i++)
{
for(int j = -800; j <= 800; j++)
{
cSummand.setRe(((double)i)/1000.0);
cSummand.setIm(((double)j)/1000.0);
this.setSummand(cSummand);
this.calcAbsSqValues();
this.getCanvas().paint(m_cCanvas.getGraphics());
this.paint(this.getGraphics());
}
}
cSummand = null;
this.collectGarbage();
System.gc();
System.runFinalization();
}
public boolean isRunning()
{
return m_bRunning;
}
public void setRunning(boolean aRunning)
{
m_bRunning = aRunning;
}
public Canvas getCanvas()
{
return m_cCanvas;
}
public void run()
{
if(m_bRunning)
{
this.handleCalculation();
}
}
}
class JuliaCanvas extends Canvas
{
private int m_iWidth;
private int m_iHeight;
private Random m_cRnd;
private BufferedImage m_cBackGroundImage = null;
private int m_iRed[][];
private int m_iGreen[][];
private int m_iBlue[][];
JuliaCanvas(int aWidth, int aHeight)
{
m_iWidth = aWidth;
m_iHeight = aHeight;
m_cRnd = new Random();
m_cRnd.setSeed(m_cRnd.nextLong());
m_cBackGroundImage = new BufferedImage(m_iWidth, m_iHeight, BufferedImage.TYPE_INT_RGB);
m_iRed = new int[m_iHeight][m_iWidth];
m_iGreen = new int[m_iHeight][m_iWidth];
m_iBlue = new int[m_iHeight][m_iWidth];
}
public void init() {
}
public void setPixelColour(int i, int j, Color aColour)
{
m_iRed[i][j] = aColour.getRed();
m_iGreen[i][j] = aColour.getGreen();
m_iBlue[i][j] = aColour.getBlue();
}
private int getRandomInt(double aProbability)
{
return (m_cRnd.nextDouble() < aProbability) ? 1 : 0;
}
#Override
public void paint(Graphics aGraphics)
{
// store on screen graphics
Graphics cScreenGraphics = aGraphics;
// render on background image
aGraphics = m_cBackGroundImage.getGraphics();
for (int i = 0; i < m_iWidth; i++)
{
for (int j = 0; j < m_iHeight; j++)
{
Color cColor = new Color(m_iRed[i][j], m_iGreen[i][j], m_iBlue[i][j]);
aGraphics.setColor(cColor);
aGraphics.drawRect(i, j, 0, 0);
cColor = null;
}
}
// rendering is done, draw background image to on screen graphics
cScreenGraphics.drawImage(m_cBackGroundImage, 1, 1, null);
}
#Override
public void update(Graphics aGraphics)
{
paint(aGraphics);
}
}
class Complex {
private double m_dRe;
private double m_dIm;
public Complex()
{
m_dRe = 0;
m_dIm = 0;
}
public Complex(double aRe, double aIm)
{
m_dRe = aRe;
m_dIm = aIm;
}
public Complex(Complex aComplex)
{
m_dRe = aComplex.m_dRe;
m_dIm = aComplex.m_dIm;
}
public double getRe() {
return m_dRe;
}
public void setRe(double adRe)
{
m_dRe = adRe;
}
public double getIm() {
return m_dIm;
}
public void setIm(double adIm)
{
m_dIm = adIm;
}
public void add(Complex acComplex)
{
m_dRe += acComplex.getRe();
m_dIm += acComplex.getIm();
}
public void square()
{
double m_dReSave = m_dRe;
m_dRe = (m_dRe * m_dRe) - (m_dIm * m_dIm);
m_dIm = 2 * m_dReSave * m_dIm;
}
public double getAbsSq()
{
return ((m_dRe * m_dRe) + (m_dIm * m_dIm));
}
}
I'm quoting a recent comment from #MadProgrammer (including links)
"Swing is single threaded, nothing you can do to change that, all events are posted to the event queue and processed by the Event Dispatching Thread, see Concurrency in Swing for more details and have a look at Worker Threads and SwingWorker for at least one possible solution"
There is only one thread in your code. That thread is busy doing the calculation and can not respond to events located in the GUI. You have to separate the calculation in another thread that periodically updates the quantities that appears in the window. More info about that in the links, courtesy of #MadProgrammer, I insist.
UPDATED: As pointed by #Yusuf, the proper way of launching the JFrame is
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new JuliaSet("Julia Set", windowWidth, windowHeight, plotWidth, plotHeight);
}
});
Set the frame visible on construction and start calculation when the start button is pressed.
First;
Endless loop is not a proper way to do this. This part is loops and taking CPU and never give canvas to refresh screen. if you add below code your code will run as expected. but this is not the proper solution.
cMain.java:
while (true) {
cJuliaSet.run();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Second: you could call run method when start button clicked. But you should create a thread in run method to not freeze screen.
public static void main(String[] args) {
int windowWidth = 1000;// (int)screenSize.getWidth() - 200;
int windowHeight = 800;// (int)screenSize.getHeight() - 50;
int plotWidth = 400;// (int)screenSize.getWidth() - 600;
int plotHeight = 400;// (int)screenSize.getHeight() - 150;
JuliaSet cJuliaSet = new JuliaSet("Julia Set", windowWidth, windowHeight, plotWidth, plotHeight);
cJuliaSet.setVisible(true);
//While loop removed
}
actionPerformed:
if (strCmd.equals("Start")) {
m_cCanvas.init();
m_cSMsg = "c = " + Double.toString(m_dReal) + " + " + "j*" + Double.toString(m_dImag);
m_bRunning = true;
this.run(); // added call run method.
} else if (aActionEvent.getSource() == m_cTReal) {
run method:
public void run()
{
if(m_bRunning)
{
new Thread(){ //Thread to release screen
#Override
public void run() {
JuliaSet.this.handleCalculation();
}
}.start(); //also thread must be started
}
}
As said by #RubioRic, SwingUtilities.invokeLater method is also a part of solution. But you need to check whole of your code and you should learn about Threads.

Java dining philosophers monitors

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();
}
}

Categories