I don't see any problem with this code, but the result doesn't display in the console window in eclipse.
What's the problem?
class Buffer{
private int data;
private boolean empty = true;
public synchronized int get() {
while(empty) {
try {
wait();
} catch (InterruptedException e) {
}
}
empty = true;
notifyAll();
return data;
}
public synchronized void put(int data) {
while (!empty) {
try {
wait();
} catch (InterruptedException e) {
}
}
empty = false;
this.data = data;
notifyAll();
}
}
class Producer implements Runnable{
private Buffer buffer;
public Producer(Buffer buffer) {
this.buffer = buffer;
}
public void run() {
for (int i=0; i<0; i++) {
buffer.put(i);
System.out.println("Producer: " + i + "th cake produced.");
try {
Thread.sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}
class Consumer implements Runnable{
private Buffer buffer;
public Consumer(Buffer drop) {
this.buffer = drop;
}
public void run() {
for(int i=0; i<10; i++) {
int data = buffer.get();
System.out.println("Consumer: " + data + "th cake comsumed.");
try {
Thread.sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}
public class ProducerConsumerTest {
public static void main(String[] args) {
Buffer buffer = new Buffer();
(new Thread(new Producer(buffer))).start();
(new Thread(new Consumer(buffer))).start();
}
}
In the run() method of the producer you have bad for loop
for (int i=0; i<0; i++)
but it should be
for (int i=0; i<10; i++)
That was probably a typo :)
I'm trying to finish my project about searching graphs, where one of the functions is input (vertex and edges) from user.
I already have a method for this in another class, but now I need to put it into GUI.
I've already tried many of tutorials, but nothing worked. Can somebody help me, how to put the method getInputFromCommand to gui?
I've already tried to copy the method into the GUI, but there was problem with the "return g" because of the void result type, I've tried just to call the method, (I know.. stupid) but it didn't work either.
package Process;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
public class FindIslands {
String message = "";
int V;
LinkedList<Integer>[] adjListArray;
static LinkedList<String> nodeList = new LinkedList<String>();
// constructor
FindIslands(int V) {
this.V = V;
adjListArray = new LinkedList[V];
for (int i = 0; i < V; i++) {
adjListArray[i] = new LinkedList<Integer>();
}
}
void addEdge(int src, int dest) {
adjListArray[src].add(dest);
adjListArray[dest].add(src);
}
void DFSUtil(int v, boolean[] visited) {
visited[v] = true;
message += getValue(v) + " ";
// System.out.print(getValue(v) + " ");
for (int x : adjListArray[v]) {
if (!visited[x]) {
DFSUtil(x, visited);
}
}
}
void connectedComponents() {
boolean[] visited = new boolean[V];
int count = 0;
message = "";
for (int v = 0; v < V; ++v) {
if (!visited[v]) {
DFSUtil(v, visited);
message += "\n";
// System.out.println();
count++;
}
}
System.out.println("" + count);
System.out.println("");
System.out.println("Vypis ostrovu: ");
String W[] = message.split("\n");
Arrays.sort(W, new java.util.Comparator<String>() {
#Override
public int compare(String s1, String s2) {
// TODO: Argument validation (nullity, length)
return s1.length() - s2.length();// comparison
}
});
for (String string : W) {
System.out.println(string);
}
}
public static void main(String[] args) {
FindIslands g = null; //
String csvFile = "nodefile.txt";
BufferedReader br = null;
String line = "";
int emptyLine = 0;
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
if (line.equals("")) {
emptyLine = 1;
// System.out.println("found blank line");
}
if (emptyLine == 0) {
// System.out.println(line);
nodeList.add(line);
} else if (line.isEmpty()) {
g = new FindIslands(nodeList.size());
} else {
String[] temp = line.split(",");
g.addEdge(getIndex(temp[0]), getIndex(temp[1]));
}
}
} catch (FileNotFoundException e) {
System.out.println("Soubor nenalezen, zadejte data v danem formatu");
g = getInputFromCommand();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Pocet ostrovu");
if (g != null) {
g.connectedComponents();
}
}
public static int getIndex(String str) {
return nodeList.indexOf(str);
}
public static String getValue(int index) {
return nodeList.get(index);
}
public static FindIslands getInputFromCommand() {
FindIslands g = null;
BufferedReader br = null;
String line = "";
int emptyLine = 0;
Scanner scanner = new Scanner(System.in);
line = scanner.nextLine();
while (!line.equals("")) {
if (line.equals("--gui")) {
Guicko gui = new Guicko();
gui.setVisible(true);
} else
nodeList.add(line);
line = scanner.nextLine();
}
g = new FindIslands(nodeList.size());
line = scanner.nextLine();
while (!line.equals("")) {
String[] temp = line.split(",");
if (temp.length != 2) {
System.out.println("spatny format zadanych dat, prosim zkuste znovu");
} else {
g.addEdge(getIndex(temp[0]), getIndex(temp[1]));
}
line = scanner.nextLine();
}
return g;
}
}
Where important is the last method "getInputFromCommand()"
and... gui
package Process;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.util.Scanner;
public class Guicko extends JFrame {
private JButton štartButton;
private JPanel panel;
private JTextField textField2;
private JTextArea textArea1;
public Guicko() {
add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setTitle("Zadej hodnoty");
setSize(500, 400);
textField2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
FindIslands.getInputFromCommand();
}
});
štartButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String str = "asd";
FindIslands g = null;
g.connectedComponents();
textArea1.setText(str);
}
});
}
public static void main (String args[]){
Guicko gui = new Guicko();
gui.setVisible(true);
}
}
I'm sure there are many correct ways this code can be fixed, but in IMHO, your Guicko class needs to have a FindIslands class member, and I think you need to move some stuff from FindIslands.main() into Guicko.main() or some other method.
Then your "Action Listener" inner classes' actionPerformed methods just delegate to the methods in the FindIslands member instance, like this
....
private FindIslands fi;
public Guicko() {
....
textField2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fi = FindIslands.getInputFromCommand();
}
});
startButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String comps = fi.connectedComponents();// method needs to return a string
textArea1.setText(comps);
}
});
}
The whole idea of seperating GUI from domain is to make changes easily. GUI has knowledge of the domain but domain has no knowledge about the GUI. We can use an interface to seperate them, in that case, Domain says , i don't care who implements this interface but whoever implements this interface will get response and can work with me.
So , If we create a new GUI, we can let it implements that interface and the same domain will work with that GUI.
There are many mistakes but in order to make it work and to show you an example i did few changes.
public class Guicko extends JFrame implements PropertyChangeListener{
private JButton štartButton;
private JPanel panel;
private JTextField textField2;
private JTextArea textArea1;
private FindIslands land;
private JTextField textField;
private JButton button;
public Guicko() {
JPanel panel = new JPanel();
super.getContentPane().setLayout(new GridLayout());
//For each gui, there should be one land.
this.setLand(new FindIslands(100));
//Subscribe to the domain so that you can get update if something change in domain.
this.getLand().subscribe(this);
//Dummy buttons are fields(need too initiate first)
textField2 = new JTextField("",30);
štartButton = new JButton();
textField = new JTextField("",30);
button = new JButton();
button.setPreferredSize(new Dimension(100, 40));
button.setText("Get input from Domain");
štartButton.setPreferredSize(new Dimension(100, 40));
textField.setEditable(false);
štartButton.setText("Start");
panel.add(textField2);
panel.add(štartButton);
panel.add(textField);
panel.add(button);
add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setTitle("Zadej hodnoty");
setSize(500, 400);
//When you type something in , then this function will send it to domain(i mean to function : getInputFromCommand();).
this.addListerToField(štartButton,this.getLand(),textField2);
//Now the second case, suppose you press a button and want something to show up in textfield. In that case , this function will do work.
this.addListerToSecondField(button,this.getLand(),textField);
}
//Here i can catch the events from the domain.
#Override
public void propertyChange(PropertyChangeEvent e) {
if(e.getPropertyName().equals("String changed")) {
this.getTextField().setText((String) e.getNewValue());
}
}
private void addListerToSecondField(JButton button, FindIslands land, JTextField field) {
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
land.requireArgumentsForField();
}
});
}
private void addListerToField(JButton štartButton, FindIslands land, JTextField field) {
štartButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
land.getInputFromCommand(field.getText());
}
});
}
public static void main (String args[]){
Guicko gui = new Guicko();
gui.setVisible(true);
}
public FindIslands getLand() {
return land;
}
public void setLand(FindIslands land) {
this.land = land;
}
public JTextField getTextField() {
return textField;
}
public void setTextField(JTextField textField) {
this.textField = textField;
}
public JButton getButton() {
return button;
}
public void setButton(JButton button) {
this.button = button;
}
Here is the second class. Run it and try to get feeling for it how it works.
public class FindIslands {
String message = "";
int V;
LinkedList<Integer>[] adjListArray;
static LinkedList<String> nodeList = new LinkedList<String>();
// constructor
FindIslands(int V) {
this.V = V;
//initialize the list
this.setListeners(new ArrayList<>());
adjListArray = new LinkedList[V];
for (int i = 0; i < V; i++) {
adjListArray[i] = new LinkedList<Integer>();
}
}
void addEdge(int src, int dest) {
adjListArray[src].add(dest);
adjListArray[dest].add(src);
}
void DFSUtil(int v, boolean[] visited) {
visited[v] = true;
message += getValue(v) + " ";
// System.out.print(getValue(v) + " ");
for (int x : adjListArray[v]) {
if (!visited[x]) {
DFSUtil(x, visited);
}
}
}
void connectedComponents() {
boolean[] visited = new boolean[V];
int count = 0;
message = "";
for (int v = 0; v < V; ++v) {
if (!visited[v]) {
DFSUtil(v, visited);
message += "\n";
// System.out.println();
count++;
}
}
System.out.println("" + count);
System.out.println("");
System.out.println("Vypis ostrovu: ");
String W[] = message.split("\n");
Arrays.sort(W, new java.util.Comparator<String>() {
#Override
public int compare(String s1, String s2) {
// TODO: Argument validation (nullity, length)
return s1.length() - s2.length();// comparison
}
});
for (String string : W) {
System.out.println(string);
}
}
//You need only one main class, not two.----------------------------
/**
public static void main(String[] args) {
FindIslands g = null; //
String csvFile = "nodefile.txt";
BufferedReader br = null;
String line = "";
int emptyLine = 0;
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
if (line.equals("")) {
emptyLine = 1;
// System.out.println("found blank line");
}
if (emptyLine == 0) {
// System.out.println(line);
nodeList.add(line);
} else if (line.isEmpty()) {
g = new FindIslands(nodeList.size());
} else {
String[] temp = line.split(",");
g.addEdge(getIndex(temp[0]), getIndex(temp[1]));
}
}
} catch (FileNotFoundException e) {
System.out.println("Soubor nenalezen, zadejte data v danem formatu");
g = getInputFromCommand();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Pocet ostrovu");
if (g != null) {
g.connectedComponents();
}
}
**/
public static int getIndex(String str) {
return nodeList.indexOf(str);
}
public static String getValue(int index) {
return nodeList.get(index);
}
//Static cases are to be avoided.This is the property of object not class.
public void getInputFromCommand(String string) {
//Here you will recieve a string from the GUI and will be printed in command prompt.You can do whatever you want to do with it.
System.out.println("Recieve string is " + string);
//No idea what you are trying to do.
/** FindIslands g = null;
BufferedReader br = null;
String line = "";
int emptyLine = 0;
Scanner scanner = new Scanner(System.in);
line = scanner.nextLine();
while (!line.equals("")) {
if (line.equals("--gui")) {
Guicko gui = new Guicko();
gui.setVisible(true);
} else
nodeList.add(line);
line = scanner.nextLine();
}
g = new FindIslands(nodeList.size());
line = scanner.nextLine();
while (!line.equals("")) {
String[] temp = line.split(",");
if (temp.length != 2) {
System.out.println("spatny format zadanych dat, prosim zkuste znovu");
} else {
g.addEdge(getIndex(temp[0]), getIndex(temp[1]));
}
line = scanner.nextLine();
}
return line;**/
}
//This function is triggered with second button and you can send data to gui as shown below.
public void requireArgumentsForField() {
//Suppose i want to send following string.
String name = "I don't know";
this.getListeners().stream().forEach(e -> {
// I will catch this in view.
e.propertyChange(new PropertyChangeEvent(this, "String changed", null, name));
});
}
private ArrayList<PropertyChangeListener> listeners;
//Let the objects subscibe. You need this to publish the changes in domain.
public void subscribe(PropertyChangeListener listener) {
this.getListeners().add(listener);
}
public ArrayList<PropertyChangeListener> getListeners() {
return listeners;
}
public void setListeners(ArrayList<PropertyChangeListener> listeners) {
this.listeners = listeners;
}
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()));
}
}
I'm not sure why the albums aren't being serialized when the users are.
In the admin class, when I login, the userlist is populated in the JCombobox<String> userlist everytime I restart the program.
But the JComboBox<Album> comboBoxAlbumSelect isn't populated every time I restart the program.
Not sure why. Thanks.
Relevant code:
public class Admin extends JFrame implements ActionListener {
Backend backend = new Backend();
GuiCtrl ctrl = new GuiCtrl(backend);
private JComboBox<String> userlist = new JComboBox<String>();
public Admin() {
//same as login
userlist = new JComboBox<String>(getUserList());
}
public String[] getUserList() {
String[] ret = new String[backend.getUserList().size()];
int i = 0;
for (String s : backend.getUserList()) {
System.out.println(s);
ret[i++] = s;
}
return ret;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == logout) {
this.dispose();
new Login();
}
else if (e.getSource() == add) {
try {
if (ctrl.adduser(idNumberTF.getText(), fullNameTF.getText())) {
userlist.addItem(idNumberTF.getText());
backend.storeData();
} catch (IOException|ClassNotFoundException i) {}
}
}
}
public class MainAlbumPanelv2 extends JFrame implements ActionListener {
JButton btnCreateAlbum = new JButton("Create");
JComboBox<Album> comboBoxAlbumSelect = new JComboBox<Album>();
Backend backend = new Backend();
GuiCtrl ctrl = new GuiCtrl(backend);
User loggedInUser;
public MainAlbumPanelv2(User id) {
loggedInUser = id;
comboBoxAlbumSelect = new JComboBox<Album>(getAlbumList());
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnCreateAlbum) {
if (ctrl.createAlbum(loggedInUser, textFieldCreateAlbum.getText())) {
Album newAlbum = new Album(textFieldCreateAlbum.getText());
comboBoxAlbumSelect.addItem(newAlbum);
}
try {
backend.storeData();
} catch (IOException i) {}
}
}
public Album[] getAlbumList() {
Album[] ret = new Album[loggedInUser.getAlbums().size()];
int i = 0;
for (Album a : loggedInUser.getAlbums()) {
System.out.println(a);
ret[i++] = a;
}
return ret;
}
}
-
public class GuiCtrl {
User loggedInUser;
Backend backend;
public GuiCtrl(Backend backend) {
this.backend = backend;
}
public boolean adduser(String user_id, String user_name) throws IOException, ClassNotFoundException {
if (backend.addUser(new User(user_id, user_name))) {
return true;
} else {
return false;
}
}
public boolean createAlbum(User user_id, String name) {
if (user_id.getAlbum(name) != null) {
return false;
} else {
user_id.addAlbum(name);
return true;
}
}
}
-
public class Backend {
private HashMap<String, User> userList = new HashMap<>();
StringTokenizer tokenizer;
public Backend() {
try {
populateList();
} catch (ClassNotFoundException | IOException e) {
throw new RuntimeException("Cannot read file");
}
}
public boolean addUser(User newUser)
{
String userId = newUser.getID();
if (userList.containsKey(userId)) {
return false;
}
userList.put(userId, newUser);
return true;
}
public void storeData() throws IOException
{
try
{
FileOutputStream file = new FileOutputStream("users.ser");
ObjectOutputStream out = new ObjectOutputStream(file);
out.writeObject(userList);
out.close();
file.close();
}
catch (IOException i)
{
i.printStackTrace();
}
}
public void populateList() throws IOException, ClassNotFoundException
{
try
{
FileInputStream file = new FileInputStream ("users.ser");
ObjectInputStream in = new ObjectInputStream(file);
userList = (HashMap<String, User>) in.readObject();
in.close();
file.close();
}
catch (IOException i)
{
i.printStackTrace();
userList = new HashMap();
}
}
}
public class Album implements Serializable{
private String name;
private ArrayList<Photo> photoList;
public Album(String name)
{
this.name = name;
photoList = new ArrayList<Photo>();
}
}
public class User implements Serializable{
private String id;
private String fullName;
private ArrayList<Album> albumList;
public User(String id, String fullName)
{
this.id = id;
this.fullName = fullName;
albumList = new ArrayList<Album>();
}
public int addAlbum(Album newAlbum)
{
Album currAlbum;
if (newAlbum == null)
{
return 0;
}
for (int x = 0; x < albumList.size(); x++)
{
currAlbum = albumList.get(x);
if (currAlbum.getName().equals(newAlbum.getName()))
{
return 0;
}
}
albumList.add(newAlbum);
return 1;
}
public ArrayList<Album> getAlbums()
{
return albumList;
}
}
Code Snippet:
public class SyncTest {
public static void main(String[] args) {
new SyncTest().test();
}
private void test() {
final Outputer outputer = new Outputer();
// Thread 1
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.outPut("一二三四五六七八九");
}
}
}).start();
// Thread2
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
Outputer.outPut2("123456789");
}
}
}).start();
}
static class Outputer {
public void outPut( String name) {
int len = name.length();
synchronized (Outputer.this) { // lock is Outputer.class
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
public static synchronized void outPut3( String name) { // lock also is Outputer.class
int len = name.length();
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
Output :
123456789
1一2二三四五六七八九
3456789
obvious no synchronized, please give a hand, thanks
You need to specify the class instance instead of this, so both use the same Monitor object
static class Outputer {
public void outPut( String name) {
int len = name.length();
synchronized (Outputer.class) { // Outputer.this is not the same as Outputer.class
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
alternatively you can use a seperate monitor object so thats explicit which will be used:
static class Outputer {
private static Object syncronisationMonitor = new Object();
// nonstatic method
public void outPut( String name) {
synchronized (syncronisationMonitor ) { // we use the same monitor as in the static method
[...]
}
}
//static method
public static void outPut3( String name) {
synchronized (syncronisationMonitor ) { // we use the same monitor as in the non-static method
[...]
}
}
}