I am making a 3 thread communication. User will input the message for the thread to communicate. The threads suppose to communicate until one of the thread says "Bye". But in my program thread 1 execute only once then gone and the other two threads continue communicate.
The Output of my program looks like this.
Here is the code:
import java.util.Scanner;
public class Conversation {
public static void main(String[] args) {
Chat chat = new Chat();
new Thread1(chat).start();
new Thread2(chat).start();
new Thread3(chat).start();
}
}
class Chat {
Scanner sc1 = new Scanner(System.in);
Scanner sc2 = new Scanner(System.in);
Scanner sc3 = new Scanner(System.in);
String str1,str2,str3;
int flag = 0;
public synchronized void getTalk1() throws InterruptedException {
if (flag==1 ) {
wait();
}
System.out.print("User1: ");
str1 = sc1.nextLine();
if(str1.equalsIgnoreCase("bye")) {
System.out.println("\nUser1 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 1;
notifyAll();
}
public synchronized void getTalk2() throws InterruptedException {
if (flag == 0) {
wait();
}
System.out.print("User2: ");
str2 = sc2.nextLine();
if(str2.equalsIgnoreCase("bye")) {
System.out.println("\nUser2 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 0;
notifyAll();
}
public synchronized void getTalk3() throws InterruptedException {
if (flag == 3) {
wait();
}
System.out.print("User3: ");
str3 = sc3.nextLine();
if(str3.equalsIgnoreCase("bye")) {
System.out.println("\nUser3 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 3;
notifyAll();
}
}
class Thread1 extends Thread {
Chat chat;
public Thread1(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.getTalk1();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Thread2 extends Thread {
Chat chat;
public Thread2(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.getTalk2();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Thread3 extends Thread {
Chat chat;
public Thread3(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.getTalk3();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You don't necessarily need to create 3 separate Thread classes for 3 users. You also don't need 3 separate methods for each user. It's hard to read, maintain, and debug.
I wrote a very simple program for you. In your application, synchronised is used to wrap the whole method. It's hard to read, and it's unclear why you synchronised the entire method body. In my example, there is a single point where synchronisation is required and it's well defined: when a user wants to say something to the chat.
Have a look.
class Application {
public static void main(String[] args) {
final Chat chat = new Chat();
chat.registerUser(new User("user1", chat));
chat.registerUser(new User("user2", chat));
chat.registerUser(new User("user3", chat));
}
}
class Chat {
private final Scanner scanner = new Scanner(System.in);
private final List<User> users = new ArrayList<>();
private void registerUser(User user) {
users.add(user);
System.out.format("'%s' connected to the chat.\n", user);
user.start();
}
public void sendMessage(User user) {
final String reply = scanner.nextLine();
System.out.format("%s: %s\n", user, reply);
if (reply.equalsIgnoreCase("bye")) {
users.forEach(Thread::interrupt);
System.out.println("The chat is over.");
} else {
notifyAll();
}
}
}
class User extends Thread {
private final String id;
private final Chat chat;
public User(String id, Chat chat) {
this.id = id;
this.chat = chat;
}
public void run() {
while (true) {
try {
synchronized (chat) {
chat.sendMessage(this);
chat.wait();
}
} catch (InterruptedException e) {
throw new IllegalArgumentException("Someone left. I am done as well.");
}
}
}
#Override
public String toString() {
return id;
}
}
An example would be
'user1' connected to the chat.
'user2' connected to the chat.
'user3' connected to the chat.
hi
user1: hi
hello
user3: hello
what's up?
user2: what's up?
nothing
user3: nothing
what?
user1: what?
bye
user2: bye
The chat is over.
To read:
the producer–consumer problem
You have 3 synchronized methods but each method is used by 1 thread only.
You have misunderstood the role of synchronized.
synchronized means an object having synchronized block does not let two threads to access the code inside the block at the same time.
Therefore, the 3 threads access one shared resource (System.in) without synchronization and the behaviour is undefined.
Hope this code helps.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Chat chat = new Chat();
new T1(chat).start();
new T2(chat).start();
new T3(chat).start();
}
}
class Chat {
Scanner sc1 = new Scanner(System.in);
Scanner sc2 = new Scanner(System.in);
Scanner sc3 = new Scanner(System.in);
String str1,str2,str3;
int flag = 1;
public synchronized void Person1() throws InterruptedException {
while(flag==2 || flag==3) {
wait();
}
System.out.print("Person 1: ");
str1 = sc1.nextLine();
if(str1.equalsIgnoreCase("bye")) {
System.out.println("\nPerson 1 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 2;
notifyAll();
}
public synchronized void Person2() throws InterruptedException {
while(flag==1 || flag==3) {
wait();
}
System.out.print("Person 2: ");
str2 = sc2.nextLine();
if(str2.equalsIgnoreCase("bye")) {
System.out.println("\nPerson 2 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 3;
notifyAll();
}
public synchronized void Person3() throws InterruptedException {
while(flag==1 || flag==2) {
wait();
}
System.out.print("Person 3: ");
str3 = sc3.nextLine();
if(str3.equalsIgnoreCase("bye")) {
System.out.println("\nPerson 3 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 1;
notifyAll();
}
}
class T1 extends Thread {
Chat chat;
public T1(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.Person1();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class T2 extends Thread {
Chat chat;
public T2(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.Person2();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class T3 extends Thread {
Chat chat;
public T3(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.Person3();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Related
I wanted to created a program to calculate average of the numbers input through console using threading in java. In the main function I never get the output of the average value from the function getAverage(). What's wrong..When I debug..program terminates but in normal run..It should terminate when I enter anything other than double value but it does not happen.
import java.util.*;
public class P1
{
private AverageCalculator ac;
private boolean stop;
public Thread inputThread,averageThread;
public P1()
{
ac = new AverageCalculator();
new UserInteraction(ac);
new ToAverage(ac);
}
public void printAverage()
{
System.out.println("Average is " + ac.getAverage());
}
private class AverageCalculator{
private double average=0,sum=0;
private int i=0;
private boolean flag=false;
private double getAverage()
{
return average;
}
private synchronized void sum(double val) {
while(flag) {
try {
wait();
} catch(InterruptedException e) { System.out.println("Thread Interrputed"); }
}
sum += val;
i++;
flag = true;
notify();
}
private synchronized void calculateAverage()
{
while(!flag) {
try {
wait();
} catch(InterruptedException e) { System.out.println("thread interrupted"); }
}
average = (sum / i);
flag = false;
notify();
}
}
private class UserInteraction implements Runnable {
private AverageCalculator ac;
//private boolean take=true;
private double input=0;
Scanner s = new Scanner(System.in);
private UserInteraction(AverageCalculator ac) {
this.ac = ac;
inputThread = new Thread(this,"Input thread");
inputThread.start();
stop=false;
}
public void run()
{
System.out.println("Enter number: ");
while(!stop) {
if(s.hasNextDouble() == false) {
stop = true;
s.close();
}
else
{
input = s.nextDouble();
s.nextLine();
ac.sum(input);
}
}
}
}
private class ToAverage implements Runnable {
private AverageCalculator ac;
private ToAverage(AverageCalculator ac)
{
this.ac = ac;
averageThread = new Thread(this,"Average doer Thread");
averageThread.start();
}
public void run()
{
while(!stop) {
ac.calculateAverage();
}
}
}
public static void main(String[] args) {
P1 p = new P1();
try
{
p.inputThread.join();
p.averageThread.join();
} catch(InterruptedException e) { System.out.println("Interrupted in Main"); }
System.out.println("Thread input alive check: " + p.inputThread.isAlive());
System.out.println("Thread average alive check: " + p.averageThread.isAlive());
p.printAverage();
}
}
I did not totally debug your code, but the issue is that you're calling wait(). This method puts your threads into wait state and a call to notify() or notifyAll() must occur to wake your threads up.
Here is a decent explanation of what is happening when the wait() method is called:
Difference Between Wait and Sleep in Java
I'm currently practicing Threads so I tasked myself to write a program that will create 2 threads. The first one will endlessly print a character and the second one will endlessly wait for input and then pass it to the first Thread. Then Thread #1 should print the passed character. Here's what I wrote:
public class A extends Thread {
public char dif;
Scanner stdin = new Scanner(System.in);
#Override
public void run() {
for (; ; ) {
dif = stdin.nextLine().charAt(0);
MyThread.setCh(dif);
}
}
}
This thread takes input and then passes it to this one:
public class MyThread extends Thread {
public static char ch;
public static void setCh(char cha) {
ch = cha;
}
public static char getCh() {
return ch;
}
#Override
public void run() {
for(;;) {
try {
Thread.sleep(300);
}
catch(InterruptedException e) {
e.printStackTrace();
}
System.out.print(getCh());
}
}
}
And what happens in the main():
MyThread endless = new MyThread();
MyThread.setCh('$');
A set = new A();
endless.start();
set.start();
However, this doesn't work as intended. No matter what I type, the program keeps printing $. Also for some reason the first time I type a character I get an Out of bounds exception.
Probably, the easiest way to approach this, is to use BlockingQueue.
Effectively, in your example the thread, that receives character from System.in is producer and the thread that prints received character is consumer.
So, here is the code that achieves your goal:
import java.util.*;
import java.util.concurrent.*;
class Setup {
public static void main(String[] args) {
BlockingQueue<Character> q = new LinkedBlockingQueue<>();
Producer p = new Producer(q);
Consumer c = new Consumer(q);
new Thread(p).start();
new Thread(c).start();
}
}
class Producer implements Runnable {
private final BlockingQueue<Character> queue;
private final Scanner scanner = new Scanner(System.in);
Producer(BlockingQueue<Character> q) { queue = q; }
public void run() {
try {
while (true) {
queue.put(produce());
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt(); // set interrupt flag
} finally {
scanner.close();
}
}
Character produce() {
return scanner.nextLine().charAt(0);
}
}
class Consumer implements Runnable {
private final BlockingQueue<Character> queue;
Consumer(BlockingQueue<Character> q) { queue = q; }
public void run() {
try {
while (true) {
consume(queue.take());
}
} catch (InterruptedException ex) {}
}
void consume(Character c) {
System.out.println("Received character: " + c);
}
}
The problem actually you have it is quite small delay in Thread.sleep(300);
Try to set sleep for a few seconds Thread.sleep(5000);. You have to type something before it will print previous char
I have an object A on which I'm updating some data every second and other objects B and C which want to use the data only once per update.
Every object work in parallel.
How can I make B and C wait for the update in A ?
I've seen some similar questions but their responses didn't help me.
I've seen that I could use a "synchronized" bloc on an object D, but they just put the bloc without telling how to instanciate or share that object.
The following code is what I use for my tests. I managed to get them working in parallel but I'm stuck with the suspending part.
This is the class for A
public class Master{
public static void main(String[] args) throws Exception {
Worker B = new Worker("B");
B.start();
Worker C = new Worker("C");
C.start();
while(true)
{
Thread.sleep(1000);
// update data
// notify every thread waiting that they can resume
}
}
}
This is the class used for B and C
public class Worker extends Thread
{
Worker(String name)
{
super("Worker " + name);
}
public void run()
{
int i = 0;
while(!this.isInterrupted())
{
// wait for A to update data
System.out.println(i);
i++;
}
System.out.println("thread interrupted");
}
}
From there, what do I need to add for the purpose I'm looking for ?
To do it very low level, only using the lang APIs, you should use wait/notifyAll.
Not that I used Main.class as an arbitrary object to synchronize
public class Main {
public static void main(String[] args) {
SharedData sharedData = new SharedData();
Worker w1 = new Worker("Worker 1", sharedData);
Worker w2 = new Worker("Worker 2", sharedData);
w1.start();
w2.start();
while (true) {
try {
Thread.sleep(1000);
sharedData.increase();;
System.out.println("Master: " + sharedData.value());
synchronized (Main.class) {
Main.class.notifyAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class SharedData {
private int data = 0;
public void increase () {
data++;
}
public int value() {
return data;
}
}
class Worker extends Thread {
private String workerName;
private SharedData sharedData;
public Worker(String workerName, SharedData sharedData) {
super();
this.workerName = workerName;
this.sharedData = sharedData;
}
#Override
public void run() {
while (true) {
try {
synchronized (Main.class) {
Main.class.wait();
}
System.out.println(workerName + ": " + sharedData.value());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Not sure if I understand you correctly, but this might be worth checking out for you:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html
Why use threads at all? Why not just do this?
public class Master {
public static void main(String[] args) {
Worker B = new Worker("B");
Worker C = new Worker("C");
while(true) {
Thread.sleep(1000);
updateData();
B.doWork();
C.doWork();
}
}
}
public class Worker
{
public void doWork() {
System.out.println(i);
i++;
}
private int i = 0;
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I'm pretty new to this whole "Sockets" and networking world.
First, I wanted to make a random chat program like "omegle" and it worked perfectly fine. I think I had some serious issues in the code, but it worked - so why bother? (I wish I did).
Now I am adding a "Multiplayer" option in my "Tic Tac Toe" game in android, it went wrong and I spent many hours figuring how to solve this problem but nothing worked, my app just kept crashing.
Here's the code for the simple chat program.
Server
public class server {
public static Map<Integer, MiniServer> clients;
public static void main(String args[]) throws IOException {
clients = new HashMap<>();
boolean listeningSocket = true;
ServerSocket serverSocket = new ServerSocket(1234);
while (listeningSocket) {
Socket socket = serverSocket.accept();
MiniServer mini = new MiniServer(socket);
if (clients.isEmpty()) {
clients.put(1, mini);
mini.setId(1);
} else {
int i = 1;
while (clients.containsKey(i))
i++;
clients.put(i, mini);
mini.setId(i);
}
mini.start();
}
serverSocket.close();
}
Client
public class client {
private static String message;
private static boolean connected;
private static boolean connectedInternet;
public static void main(String args[]) throws UnknownHostException, IOException {
Scanner textReader = new Scanner(System.in);
Socket socket = new Socket("127.0.0.1", 1234);
Scanner inputStreamReader = new Scanner(socket.getInputStream());
connectedInternet = true;
System.out.println("Hello Stranger, get ready to chat.");
PrintStream printStream = new PrintStream(socket.getOutputStream());
Thread getMessage = new Thread() {
public void run() {
while (true) {
message = textReader.nextLine();
if (!connected)
System.out.println("You are not connected to another Stranger yet, please wait.");
else
printStream.println(message);
}
}
};
getMessage.start();
while (connectedInternet) {
String temp = inputStreamReader.nextLine();
if (temp.equals("connected")) {
connected = true;
System.out.println("Found a Stranger, say hey !");
} else if (connected) {
if (temp.equals("!close")) {
System.out.println("Stranger disconnected.");
printStream.println("!new");
} else
System.out.println("Stranger: " + temp);
}
}
textReader.close();
socket.close();
inputStreamReader.close();
}
MiniServer
public class MiniServer extends Thread {
private Socket socket = null;
public int id;
private boolean foundPlayer;
private int colleague;
private boolean connected;
public MiniServer(Socket socket) {
super("MiniServer");
this.socket = socket;
}
public void run() {
Scanner inputStreamReader = null;
String message;
try {
inputStreamReader = new Scanner(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
PrintStream p = null;
try {
p = new PrintStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
List<Integer> keys = new ArrayList<Integer>(server.clients.keySet());
while (!foundPlayer) {
for (Integer key : keys) {
if (!server.clients.get(key).foundPlayer && key != id) {
server.clients.get(key).foundPlayer = true;
foundPlayer = true;
server.clients.get(key).colleague = id;
colleague = server.clients.get(key).id;
}
}
try {
keys = new ArrayList<Integer>(server.clients.keySet());
} catch (ConcurrentModificationException e) {
}
}
p.println("connected");
connected = true;
while (connected) {
try {
message = inputStreamReader.nextLine();
if (message.equals("!new")) {
foundPlayer = false;
keys = new ArrayList<Integer>(server.clients.keySet());
while (!foundPlayer) {
for (Integer key : keys) {
if (!server.clients.get(key).foundPlayer && key != id) {
server.clients.get(key).foundPlayer = true;
foundPlayer = true;
server.clients.get(key).colleague = id;
colleague = server.clients.get(key).id;
}
}
try {
keys = new ArrayList<Integer>(server.clients.keySet());
} catch (ConcurrentModificationException e) {
}
}
p.println("connected");
} else
sendToClient(message);
} catch (NoSuchElementException e) {
server.clients.remove(id);
sendToClient("!close");
closeSocket();
connected = false;
}
}
}
public void setId(int i) {
id = i;
}
public void sendToClient(String message) {
Socket colleagueSocket = server.clients.get(colleague).socket;
PrintStream rr = null;
try {
rr = new PrintStream(colleagueSocket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
rr.println(message);
}
public void closeSocket() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
This program works great, but I'm pretty sure there are tons of problems with it.
Now here's my Server-side code for my android application.
Server
public class Server {
public static Map<Integer, MiniServer> clients;
public static void main(String args[]) throws IOException {
clients = new HashMap<>();
boolean listeningSocket = true;
ServerSocket serverSocket = new ServerSocket(1234);
while (listeningSocket) {
Socket socket = serverSocket.accept();
MiniServer mini = new MiniServer(socket);
if (clients.isEmpty()) {
clients.put(1, mini);
mini.setId(1);
} else {
int i = 1;
while (clients.containsKey(i))
i++;
clients.put(i, mini);
mini.setId(i);
}
mini.start();
}
serverSocket.close();
}
Mini Server
public class MiniServer extends Thread {
private Socket socket;
private Socket colleagueSocket;
public int id;
private boolean foundPlayer;
private int colleague;
private boolean connected;
private String crossOrCircle;
private boolean thisGoes;
private Thread timeOut;
private PrintStream p;
private Timer timer;
public MiniServer(Socket socket) {
super("MiniServer");
this.socket = socket;
}
public void run() {
Scanner inputStreamReader = null;
String message;
try {
inputStreamReader = new Scanner(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
try {
p = new PrintStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
List<Integer> keys = new ArrayList<Integer>(Server.clients.keySet());
while (!foundPlayer) {
for (Integer key : keys) {
if (!Server.clients.get(key).foundPlayer && key != id) {
Server.clients.get(key).foundPlayer = true;
foundPlayer = true;
Server.clients.get(key).colleague = id;
colleague = Server.clients.get(key).id;
crossOrCircle = "X";
Server.clients.get(key).crossOrCircle = "O";
thisGoes = true;
Server.clients.get(key).thisGoes = false;
colleagueSocket=Server.clients.get(key).colleagueSocket;
Server.clients.get(key).colleagueSocket=socket;
}
}
try {
keys = new ArrayList<Integer>(Server.clients.keySet());
} catch (ConcurrentModificationException e) {
}
}
p.println("connected");
connected = true;
p.println(crossOrCircle);
while (connected) {
try {
message = inputStreamReader.nextLine();
if (Character.toString(message.charAt(0)).equals(crossOrCircle) && thisGoes) {
p.println(message);
sendToClient(message);
thisGoes = false;
Server.clients.get(colleague).thisGoes = true;
} else if (message.equals("!close")) {
sendToClient("!closeClient");
p.println("!closeClient");
Server.clients.get(colleague).connected = false;
connected = false;
Server.clients.get(colleague).closeSocket();
closeSocket();
Server.clients.remove(colleague);
Server.clients.remove(id);
} else if (message.equals("!pause")) {
timeOut = new Thread() {
#Override
public void run() {
timer = new Timer();
timer.schedule(
new TimerTask() {
#Override
public void run() {
sendToClient("!closeClient");
p.println("!closeClient");
Server.clients.get(colleague).connected = false;
connected = false;
Server.clients.get(colleague).closeSocket();
closeSocket();
Server.clients.remove(colleague);
Server.clients.remove(id);
}
},
5000
);
}
};
timeOut.start();
} else if (message.equals("!resume")) {
timer.cancel();
}
} catch (NoSuchElementException e) {
sendToClient("!closeClient");
p.println("!closeClient");
Server.clients.get(colleague).connected = false;
connected = false;
Server.clients.get(colleague).closeSocket();
closeSocket();
Server.clients.remove(colleague);
Server.clients.remove(id);
}
}
}
public void setId(int i) {
id = i;
}
public void sendToClient(String message) {
PrintStream rr = null;
try {
rr = new PrintStream(colleagueSocket.getOutputStream());
} catch (IOException | NullPointerException e) {
e.printStackTrace();
}
rr.println(message);
}
public void closeSocket() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public Socket getSocket(){
return this.socket;
}
There's a problem in the sendClient() method, it keeps throwing NullPointerException.
What can I do? I'm not asking you to solve my problem.
Could you give me some advices please?
Thank you very much :)
Edit:
I forgot to mention some thing- I'm running the server on my computer and I'm using two different devices that are connected to the LAN.
java.lang.NullPointerException
at com.ilya.rabinovich.tictactoe.MiniServer.sendToClient(MiniServer.java:134)
at com.ilya.rabinovich.tictactoe.MiniServer.run(MiniServer.java:75)
Exception in thread "MiniServer" java.lang.NullPointerException
at com.ilya.rabinovich.tictactoe.MiniServer.sendToClient(MiniServer.java:138)
at com.ilya.rabinovich.tictactoe.MiniServer.run(MiniServer.java:75)
Edit 2:
I fixed this exception by changing this line
colleagueSocket=Server.clients.get(key).colleagueSocket;
To
colleagueSocket=Server.clients.get(key).socket;
When running this app on the android emulators (android studio) it works perfectly fine, but when I try running this app on external devices (Lg g3 and nexus 7) it works really weird and crashes most of the times.
Edit 3:
Okay I solved the problem =)
The problem was in the client(runOnUiThread).
Anyways, do you think there are ways to improve my Server code? Thanks !
I don't know if you already did, but you need to whitelist the server ip in your config.xml file.
This might be one one reason.
I've written server app, which works on few threads. We have networking thread to connect and exchange data with client app, dataBaseConnector thread, which connect with sqlite data base, and userInterface thread, which is for simple control of the program.
Main:
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(9000);
DataContainer dataContainer = new DataContainer();
DataBaseConnector dataBaseConnector = new DataBaseConnector(dataContainer);
UserInterface userInterface = new UserInterface(dataBaseConnector, dataContainer);
Thread userInterfaceThread = new Thread(userInterface);
Thread dataBaseConnectorThread = new Thread(dataBaseConnector);
userInterfaceThread.start();
dataBaseConnectorThread.start();
while(dataContainer.workingStatus){
new Thread(new Handler(new Networking(dataContainer, serverSocket.accept()))).start();
}
}
}
User Interface:
public class UserInterface implements Runnable {
private final String WELCOME = "Witaj w programie Auction House! Jest to serwer aplikacji";
private final String MENU = "Menu:";
private final String OPTION_ONE = "1. Zapisz dane do bazy";
private final String OPTION_TWO = "2. Zamknij serwer";
private final String OPTION_THREE = "3. Przywroc menu";
private DataBaseConnector dataBaseConnector;
private DataContainer dataContainer;
private int userChoice = 0;
public UserInterface(DataBaseConnector dataBaseConnector, DataContainer dataContainer) {
this.dataBaseConnector = dataBaseConnector;
this.dataContainer = dataContainer;
setUpMenu();
}
#Override
public void run() {
while (dataContainer.workingStatus){
getUserChoice();
makeUserRequest();
}
}
private void setUpMenu() {
System.out.println(WELCOME);
System.out.println(MENU);
System.out.println(OPTION_ONE);
System.out.println(OPTION_TWO);
System.out.println(OPTION_THREE);
}
private void getUserChoice() {
Scanner scanner = new Scanner(System.in);
userChoice = scanner.nextInt();
}
private void makeUserRequest() {
switch (userChoice) {
case 1: {
dataContainer.lockTheLock();
dataContainer.checkPoint = true;
dataContainer.unlockTheLock();
break;
}
case 2: {
dataContainer.lockTheLock();
dataContainer.workingStatus = false;
dataContainer.unlockTheLock();
break;
}
case 3: {
setUpMenu();
break;
}
}
}
}
1 - is for writing data into Data Base
2 - is for shutting down server
3 - is for printing menu again
and DataBaseConnector (short version):
public DataBaseConnector(DataContainer dataContainer) {
getJDBCDriverClass();
connection = connectToDataBase();
statement = createStatement();
this.dataContainer = dataContainer;
createTables();
selectDataFromDataBase();
updateDataContainer();
clearLists();
}
#Override
public void run() {
while (dataContainer.workingStatus) {
if (dataContainer.checkPoint) {
dataContainer.lockTheLock();
dropTables();
createTables();
setClientList();
setAuctionList();
setItemList();
instertDataIntoDataBase();
dataContainer.checkPoint = false;
dataContainer.unlockTheLock();
}
}
}
And the lock:
public class Lock {
private boolean isLocked = false;
public synchronized void lock() throws InterruptedException {
while (isLocked) {
wait();
}
isLocked = true;
}
public synchronized void unlock() {
isLocked = false;
notifyAll();
try {
wait(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
And the problem: When running in debug mode in eclipse, everything works fine, but in real time when i'm choosing 1 in console nothing is happening, but when choosing 3, the menu prints again.
When you work in Eclipse, the program is on your computer, but when you work on a network there may be a problem on firewall of network. Check that the 9000 port that uses the socket is open on the firewall, of course only in the network in which you use it.