Problems initiating class that will be updated by multiple threads - java

Hi i'm trying to create a sever/client program that takes up to 5 clients inputting a string each via multiple server side threads, these strings are to be added to team class ie the Same team, then when the team is full, clients disconnect and the server awaits names for the next Team.
My problem lies in creating an instance of the class Team that each thread updates to..
im not sure where to declare the instance of the class?(it contains a string array[5])
my classes on serverside are currently "TeamServer", "TeamServerThread" "team" "streamSocket"
Below is my "TeamServerThread" currently taking the user string and just adding it to another string.
import java.io.*;
class TeamServerThread implements Runnable {
static String names ="";
MyStreamSocket myDataSocket;
TeamServerThread(MyStreamSocket myDataSocket) {
this.myDataSocket = myDataSocket;
}
public void run( ) {
String newName;
try {
newName = myDataSocket.receiveMessage();
/**/ System.out.println("Name Recieved = "+newName);
updateNames(newName);
// now send the names to the requestor
// wait
myDataSocket.sendMessage(names);
myDataSocket.close();
}// end try
catch (Exception ex) {
System.out.println("Exception caught in thread: " + ex);
} // end catch
} //end run
private synchronized void updateNames (String newName) {
names +=newName + "\n";
// this.team.add(newName);
} // end updateNames
} // end Team
Here is my "Team" class
public class Team
{
public final int TEAM_SIZE = 5;
public String names[] = new String[TEAM_SIZE];
public int num_members = 0;
// waits until five names have arrived
// needs to be synchronized because it can be accessed
// by a number of concurrent threads
synchronized void add(String name)
{
names[num_members] = name;
num_members++;
if (num_members < TEAM_SIZE)
try
{
wait();
}
catch(Exception e) {}
else
try
{
notifyAll();
}
catch(Exception e){}
} // end add
public int Getnum_members()
{
return num_members;
}
} // end Team

All class loading is single threaded and you cannot laod/update a class with multiple threads. However I assume this is not what you mean.
You need to have the Team where every socket can see it. The problem you have is that you haven't synchronized access or replacement of the Team so you could ahve a race condition where too many client try to add themselves to the same team.
I suggest you have some type of TeamCoordinator which is passed to each socket connection which can determine when Team a client should be added to.

Related

What is the correct way to avoid an empty synchronized block?

Recently I've started looking into multithreading, and I have a question, perhaps more experienced ones could help.
My program creates two parallel threads, each of them prints counts from 0 to 19 (the NumbersPrinter class, which implements the Runnable interface).
class NumbersPrinter implements Runnable {
private Mediator mediator;
private String name;
private int makeActionOnCount;
public NumbersPrinter(Mediator mediator, String name, int makeActionOnCount) {
this.mediator = mediator;
this.name = name;
this.makeActionOnCount = makeActionOnCount;
}
#Override
public void run() {
for(int i = 0; i<20; i++){
try {
synchronized(this.mediator) {
if(this.mediator.actionInProgress.get()) {
System.out.println(name + " waits");
wait();
}
}
System.out.println(this.name + " says " + i);
Thread.sleep(500);
if(i == makeActionOnCount) {
synchronized(this.mediator) {
System.out.println(this.name + " asks Mediator to perform action...");
this.mediator.performAction();
this.mediator.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
When one of the threads reaches a certain number (defined in the makeActionOnCount variable), it starts performing a certain action that stops the execution of the second counter. The action lasts 5 seconds and after that both counters continue to count.
The counters are interconnected through an instance of the Mediator class, the performAcyion() method also belongs to the instance of the Mediator class.
import java.util.concurrent.atomic.AtomicBoolean;
class Mediator {
public AtomicBoolean actionInProgress = new AtomicBoolean(false);
public Mediator() {
}
public void performAction() throws InterruptedException {
actionInProgress.set(true);
System.out.println("Action is being performed");
Thread.sleep(5000);
System.out.println("Action has been performed");
actionInProgress.set(false);
}
}
Here's the Main class:
class Main {
public static void main(String[] args) throws InterruptedException{
Mediator mediator = new Mediator();
NumbersPrinter data = new NumbersPrinter(mediator, "Data", 10);
NumbersPrinter lore = new NumbersPrinter(mediator, "Lore", 5);
Thread oneThread = new Thread(data);
Thread twoThread = new Thread(lore);
System.out.println("Program started");
oneThread.start();
twoThread.start();
oneThread.join();
twoThread.join();
System.out.println("Program ended");
}
The way the program is written now - works fine, but I don't quite understand what exactly should I write in the first synchronized block, because if you delete all content from it, the program still works, since the counter that does not execute the performAction() method stops 'cause the counter cannot access the monitor of the Mediator object 'cause it is busy with the parallel counter. AtomicBoolean variable and checking it also makes no sense.
In other words, I may not use the wait () and notify () constructs at all, as well as the value of the AtomicBoolean variable, and just check access to the Mediator object's monitor every new iteration using an empty synchronized block. But I've heard that an empty synchronized block is a bad practice.
I am asking for help on how to rewrite the program to use the synchronized block and the wait() and notify() methods correctly.
Maybe I'm syncing on the wrong object? How would you solve a similar problem?
Thanks in advance

Understanding java multithread synchronization

I have trouble understanding output of following code.
My understanding is output would not have any particular sequence but PlayerX started, PlayerX and PlayerX died should be in sequence.And we should have all players should in buffer log and should be printed in end.
But sometime sequence is PlayerX started,PlayerX died and then PlayerX and these cases player name is not in buffer sting. Can someone please point what I am missing?
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Game {
public static void main(String[] args) {
Ball gameBall = new Ball();
ExecutorService executor = Executors.newFixedThreadPool(5);
Player[] players = new Player[50];
for (int i = 0; i < players.length; i++) {
Player playerTemp = new Player("Player" + i, gameBall);
executor.submit(playerTemp);
players[i] = playerTemp;
System.out.println(players[i].getName1() + " started");
}
for (int i = 0; i < players.length; i++) {
try {
players[i].join();
System.out.println(players[i].getName1() + " died");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* here all thread should die and following line should display
*all player name
* without any particular order
and should be last line.
*/
executor.shutdown();
System.out.println(gameBall.getLog());
}
}
...
class Player extends Thread {
private final String name;
private final Ball ball;
public Player(String aName, Ball aBall) {
name = aName;
ball = aBall;
}
#Override
public void run() {
ball.kick(name);
}
/**
* #return the name
*/
public String getName1() {
return name;
}
}
...
class Ball {
private volatile StringBuffer log;
public Ball() {
log = new StringBuffer();
}
public synchronized void kick(String aPlayerName) {
log.append(aPlayerName + " ");
System.out.println(aPlayerName);
}
public String getLog() {
return log.toString();
}
}
First off: If you add an extra Thread.sleep(100); to the Player.run()-method you will greatly increase the probability that your code behaves wrongly.
Your understanding of multithreading is actually correct.
However your call to players[i].join(); has not the desired effect as you never started the thread players[i].
Instead you submitted it to a ExecutorService. This ExecutorService executes the Player by calling its run()-method from one of its existing threads. In your case their are 5 threads that execute the work of all Players.
To get the desired results you have 2 possibilities:
Do not use the ExecutorService, but call start() directly:
for (int i = 0; i < players.length; i++) {
Player playerTemp = new Player("Player" + i, gameBall);
playerTemp.start();
players[i] = playerTemp;
System.out.println(players[i].getName1() +" started");
}
Use executor.awaitTermination(..) instead of Thread.join():
executor.shutdown();
while(!executor.isTerminated()) {
try {
executor.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I have tried your code, and every time I see all players in the log, just in a different order. It's easier to check the log if you use an ArrayList instead of a StringBuffer, then you can print the size of the array, which always returns 50 in my tests.
In your code you get "PlayerX" and "PlayerX started" in the wrong order sometimes, because "PlayerX started" is printed after the thread is started in which "PlayerX" is printed. The main thread and the player thread run concurrently, so their order is unpredictable.
I don't see how you can get "PlayerX died" before "PlayerX", and I don't see that behaviour in my tests...

Java thread exercise: Access control to a limited resource not working [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have this situation: there is a pizzeria with a various number of customers. The pizzeria prepares a random number of pizzas before open and it has only 10 seats.
Every customer is a thread. I need to make them eat at the same time while there are free seats. The others wait until there is a free set (and until there are prepared pizzas). I tried this solution, but in this way every customer eat alone. Only when it finished another customer can eat. What's the correct solution?
This method of Pizzeria is called by every Customer thread:
public boolean eatPizza(Integer nPizzas){
if(freeSeats< 1){
try {
wait();
} catch (InterruptedException ex) {
}
}
if(preparedPizzas == 0) //Pizzas terminated for this evening
return false;
freeSeats--;
if(nPizzas > preparedPizzas)
nPizzas = preparedPizzas; //if he wants more pizzas than avaiable ones he have to settle
preparedPizzas-= nPizzas;
try {
Thread.sleep(2000); //Time for eat
} catch (InterruptedException ex) {
}
freeSeats++;
servedCustomers++;
servedPizzas+= nPizzas;
if(preparedPizzas> 0){
notify();
}
else{
notifyAll(); //Pizzas are terminated for this evening
}
return true;
}
Customer thread:
public void run(){
int wait = (int)(Math.random() * 5000);
try {
Thread.sleep(wait);
} catch (InterruptedException ex) {
}
nPizzas = (int)(Math.random() * 2 + 1); //He eats 1 or 2 pizzas random
if(pizzeria.eatPizza(nPizzas))
fireEatenEvent();
}
Thank you for your help
I created a simple example using an ExecutorService and a BlockingQueue.
This way you don't have to handle any locks on your own.
public class Restaurant {
public static void main(String[] args) throws Exception {
final Random rnd = new Random();
// The queue from which the pizzas are taken
final BlockingQueue<Pizza> pizzas = new LinkedBlockingQueue<>();
// The threadpool that represents the seats of the restaurant
// 10 customers are handled at one time
final ExecutorService seats = Executors.newFixedThreadPool(10);
final int nPizzas = rnd.nextInt(50);
final int nCustomers = rnd.nextInt(100);
System.out.println("There are " + nPizzas + " pizzas for " + nCustomers + " customers.");
// Put some pizzas into the queue
for (int i = 1; i < nPizzas + 1; i++) {
pizzas.put(new Pizza("Pizza " + i));
}
// Marks the end of the queue
pizzas.put(new PoisonPizza());
// Create some customers and send them to the restaurant
for (int i = 1; i < nCustomers + 1; i++) {
seats.submit(new Customer("Customer " + i, pizzas));
}
// Knock off when all customers are gone
seats.shutdown();
}
private static class Pizza {
private String name;
public Pizza() {}
public Pizza(final String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
private static class PoisonPizza extends Pizza {
public PoisonPizza() {
super("PoisonPizza");
}
}
private static class Customer implements Runnable {
private String name;
private BlockingQueue<Pizza> pizzas;
public Customer() {}
public Customer(final String name, final BlockingQueue<Pizza> pizzas) {
this.name = name;
this.pizzas = pizzas;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BlockingQueue<Pizza> getPizzas() {
return pizzas;
}
public void setPizzas(final BlockingQueue<Pizza> pizzas) {
this.pizzas = pizzas;
}
#Override
public void run() {
try {
// Order a pizza
final Pizza pizza = pizzas.take();
// Leave the restaurant if all pizzas have been aten
if (pizza instanceof PoisonPizza) {
pizzas.put(pizza);
System.out.println(name + ": I'm so hungry.");
return;
}
// Eat the pizza
System.out.println(name + ": " + pizza.getName() + " was delicious!");
} catch (InterruptedException e) {
return;
}
}
}
}
I tried this solution, but in this way every customer eat alone. Only when it finished another customer can eat
I see invocations to wait() and notifyAll() without any synchronized block. You must own the monitor or else you will have an IllegalMonitorStateException.
Therefore I assume there is a missing synchronized block somewhere, which would explain why it is executed by just a thread at a time.
I would had implemented this Semaphore mechanism (you are controlling the access to a resource with N positions available) in a bit different way (in this case restraining to basic Java synchronization facilities as in your code).
/**
* Lock for controlling seat adquisition (using primitive synchronization).
* Might as well use {#link java.util.concurrent.Semaphore}
*/
private final Object seatLock = "seatLock";
private int availableSeats = 10; // init as preferred
private int availablePizzas = new Random().nextInt(100);
/**
* Invoke before critical section for seat.
* Similar to {#link java.util.concurrent.Semaphore#acquire()}
* #throws InterruptedException Thread was interrupted. Might want to finalize in a civilized manner.
*/
public void acquireSeat() throws InterruptedException {
synchronized(seatLock) {
// If no available seats, wait until one is released.
while (availableSeats <= 0) {
seatLock.wait();
}
availableSeats--;
}
}
/**
* Variation of {#link #acquireSeat()} to get available pizzas at the same time.
* If (availablePizzas == 0) then No seat is acquired.
* #return Number of pizzas actually acquired, that is min(availablePizzas, requested).
*/
public int acquireSeatAndPizzas(int requested) throws InterruptedException {
assert requested > 0;
synchronized(seatLock) {
// Wait if there is pizza, but no seats.
while (availablePizzas > 0 && availableSeats <= 0) {
seatLock.wait();
}
if (availablePizzas == 0) {
seatLock.notify(); // wake up next waiting customer before leaving.
return 0;
} else {
availableSeats--;
requested = Math.min(availablePizzas, requested);
availablePizzas -= requested;
seatLock.notify(); // extra notify, in case many customers left.
return requested;
}
}
}
/**
* Invoke after critical section for seat.
* Similar to {#link java.util.concurrent.Semaphore#release()}
* Might want to do in a finally block. Might want to invoke this even on premature return or exception.
*/
public void releaseSeat() {
synchronized(seatLock) {
availableSeats++;
// Once a seat is released, notify a waiting thread.
// Might as well use #notifyAll() if other threads might be waiting on same lock for different reasons.
seatLock.notify();
}
}
The customer threads might do something like this
try {
// acquireSeat();
// try {
int requestedPizzas = new Random().nextInt(2) + 1;
int servedPizzas = acquireSeatAndPizzas(requestedPizzas);
if (servedPizzas > 0) try {
// ### Eat pizza or whatever
} finally {
releaseSeat();
}
} catch (InterruptedException e) {
// Your thread was interrupted (while waiting or elsewhere)
// ### handle here and/or propagate
}
Note1: As Andy Brown points. You can use java.util.concurrent.Semaphore, which can save you some coding and errors. However an example with basic Java synchronization might be useful in some cases. And the acquireSeatAndPizzas(I added after comments) exceeds a simple semaphore functionality.
To this regard, the answer by Steffen provides already an alternative approach using Java concurrency components (no semaphore, though).
Note2: The code above has been modified to check the number of pizzas available. It has become not trivial and did not test it (and even if I did it could never be thorough enough). Trust it at your own risk.

Is there a faster method for a NSLookup than InetAddress.getByName()?

My goal is to check a big list of domains as fast as possible. The method InetAddress.getByName() seems to be a little bit slow for me. In PHP there's gethostbyname('www.example.com')which seems to work faster. Is there an equivalent in Java which is faster? or is there a way to speed it up?
NSLookups take time because of the network infrastructure, but you can make the check in paralell. Write a thread that make the lookup and run multiple instances of it in paralell.
class LookUpThread implements Runnable {
String name;
public LookUpThread() {
}
public LookUpThread(String Name) {
this.name = Name;
}
public void run()
{
try
{
InetAddress address = InetAddress.getByName(this.name);
System.out.println(address.getHostAddress());
}
catch (Exception E) {
System.out.println("Exception " + E.getMessage());
}
}
}
And in you main:
String[] adds = new String[]{"example.com", "example.com"};
for(int i = 0; i < adds.length; i++)
new LookUpThread(adds[i]).run();

How do i prevent my consumer-threads from removing the last element twice?

Questions:
Why do I get a NoSuchElementException when trying to remove the last
element?
How can I fix that?
I have 3 classes (see below) that add/remove Integers to a LinkedList.
Everything works fine until the removing Threads get to the last element.
It seems like both threads try to remove it. The first one succeeds, the second one canĀ“t.
But I thought the synchronized-method/synchroniced-attribute + !sharedList.isEmpty() would handle that.
Class Producer:
This class is supposed to created random numbers, put them in the sharedList, write to console that it just added a number and stop once it gets interrupted. Only 1 thread of this class is expected.
import java.util.LinkedList;
public class Producer extends Thread
{
private LinkedList sharedList;
private String name;
public Producer(String name, LinkedList sharedList)
{
this.name = name;
this.sharedList = sharedList;
}
public void run()
{
while(!this.isInterrupted())
{
while(sharedList.size() < 100)
{
if(this.isInterrupted())
{
break;
} else
{
addElementToList();
}
}
}
}
private synchronized void addElementToList()
{
synchronized(sharedList)
{
sharedList.add((int)(Math.random()*100));
System.out.println("Thread " + this.name + ": " + sharedList.getLast() + " added");
}
try {
sleep(300);
} catch (InterruptedException e) {
this.interrupt();
}
}
}
Class Consumer: This class is supposed to remove the first element in the sharedList, if it exists. The execution should continue (after being interrupted) until sharedList is empty. Multiple (atleast 2) threads of this class are expected.
import java.util.LinkedList;
public class Consumer extends Thread
{
private String name;
private LinkedList sharedList;
public Consumer(String name, LinkedList sharedList)
{
this.name = name;
this.sharedList = sharedList;
}
public void run()
{
while(!this.isInterrupted())
{
while(!sharedList.isEmpty())
{
removeListElement();
}
}
}
private synchronized void removeListElement()
{
synchronized(sharedList)
{
int removedItem = (Integer) (sharedList.element());
sharedList.remove();
System.out.println("Thread " + this.name + ": " + removedItem + " removed");
}
try {
sleep(1000);
} catch (InterruptedException e) {
this.interrupt();
}
}
}
Class MainMethod: This class is supposed to start and interrupt the threads.
import java.util.LinkedList;
public class MainMethod
{
public static void main(String[] args) throws InterruptedException
{
LinkedList sharedList = new LinkedList();
Producer producer = new Producer("producer", sharedList);
producer.start();
Thread.sleep(1000);
Consumer consumer1 = new Consumer("consumer1", sharedList);
Consumer consumer2 = new Consumer("consumer2", sharedList);
consumer1.start();
consumer2.start();
Thread.sleep(10000);
producer.interrupt();
consumer1.interrupt();
consumer2.interrupt();
}
}
Exception: This is the exact exception I get.
Exception in thread "Thread-2" java.util.NoSuchElementException at
java.util.LinkedList.getFirst(LinkedList.java:126) at
java.util.LinkedList.element(LinkedList.java:476) at
Consumer.removeListElement(Consumer.java:29) at
Consumer.run(Consumer.java:20)
Your exception is rather simple to explain. In
while(!sharedList.isEmpty())
{
removeListElement();
}
sharedList.isEmpty() happens outside of synchronization and so one consumer can still see a list as empty while another consumer has already taken the last element.
The consumer that wrongfully believed it is empty will not try to remove an element that is no longer there which leads to your crash.
If you want to make it threadsafe using a LinkedList you'll have to do every read / write operation atomic. E.g.
while(!this.isInterrupted())
{
if (!removeListElementIfPossible())
{
break;
}
}
and
// method does not need to be synchronized - no thread besides this one is
// accessing it. Other threads have their "own" method. Would make a difference
// if this method was static, i.e. shared between threads.
private boolean removeListElementIfPossible()
{
synchronized(sharedList)
{
// within synchronized so we can be sure that checking emptyness + removal happens atomic
if (!sharedList.isEmpty())
{
int removedItem = (Integer) (sharedList.element());
sharedList.remove();
System.out.println("Thread " + this.name + ": " + removedItem + " removed");
} else {
// unable to remove an element because list was empty
return false;
}
}
try {
sleep(1000);
} catch (InterruptedException e) {
this.interrupt();
}
// an element was removed
return true;
}
The same problem exists within your producers. But they would just create a 110th element or something like that.
A good solution to your problem would be using a BlockingQueue. See the documentation for an example. The queue does all the blocking & synchronization for you so your code does not have to worry.
Edit: regarding 2 while loops: You don't have to use 2 loops, 1 loop loops enough but you'll run into another problem: consumers may see the queue as empty before the producers have filled it. So you either have to make sure that there is something in the queue before it can be consumed or you'll have to stop threads manually in other ways. You thread.sleep(1000) after starting the producer should be rather safe but threads are not guaranteed to be running even after 1 second. Use e.g. a CountDownLatch to make it actually safe.
I am wondering why you are not using the already existing classes that Java offers. I rewrote your program using those, and it becomes much shorter and easier to read. In addition the lack of synchronized, which blocks all threads except for the one who gets the lock (and you even do double synchronization), allows the program to actually run in parallel.
Here is the code:
Producer:
public class Producer implements Runnable {
protected final String name;
protected final LinkedBlockingQueue<Integer> sharedList;
protected final Random random = new Random();
public Producer(final String name, final LinkedBlockingQueue<Integer> sharedList) {
this.name = name;
this.sharedList = sharedList;
}
public void run() {
try {
while (Thread.interrupted() == false) {
final int number = random.nextInt(100);
sharedList.put(number);
System.out.println("Thread " + this.name + ": " + number);
Thread.sleep(100);
}
} catch (InterruptedException e) {
}
}
}
Consumer:
public class Consumer implements Runnable {
protected final String name;
protected final LinkedBlockingQueue<Integer> sharedList;
public Consumer(final String name, final LinkedBlockingQueue<Integer> sharedList) {
this.name = name;
this.sharedList = sharedList;
}
public void run() {
try {
while (Thread.interrupted() == false) {
final int number = sharedList.take();
System.out.println("Thread " + name + ": " + number + " taken.");
Thread.sleep(100);
}
} catch (InterruptedException e) {
}
}
}
Main:
public static void main(String[] args) throws InterruptedException {
final LinkedBlockingQueue<Integer> sharedList = new LinkedBlockingQueue<>(100);
final ExecutorService executor = Executors.newFixedThreadPool(4);
executor.execute(new Producer("producer", sharedList));
Thread.sleep(1000);
executor.execute(new Consumer("consumer1", sharedList));
executor.execute(new Consumer("consumer2", sharedList));
Thread.sleep(1000);
executor.shutdownNow();
}
There are several differences:
Since I use a concurrent list, I do not have to care (much) about synchronization, the list does that internally.
As this list uses atomic locking instead of true blocking via synchronized it will scale much better the more threads are used.
I do set the limit of the blocking queue to 100, so even while there is no check in the producer, there will never be more than 100 elements in the list, as put will block if the limit is reached.
I use random.nextInt(100) which is a convenience function for what you used and will produce a lot less typos as the usage is much clearer.
Producer and Consumer are both Runnables, as this is the preferred way for threading in Java. This allows to later on wrap any form of thread around them for execution, not just the primitive Thread class.
Instead of the Thread, I use an ExecutorService which allows easier control over multiple threads. Thread creation, scheduling and other handling is done internally, so all I need to do is to choose the most appropriate ExecutorService and call shutdownNow() when I am done.
Also note that there is no need to throw an InterruptedException into the void. If the consumer/producer is interrupted, that is a signal to stop execution gracefully as soon as possible. Unless I need to inform others "behind" that thread, there is no need to throw that Exception again (although no harm is done either).
I use the keyword final to note elements that won't change later on. For once this is a hint for the compiler that allows some optimizations, it as well helps me to prevent an accidental change of a variable that is not supposed to change. A lot of problems can be prevented by not allowing variables to change in a threaded environment, as thread-issues almost always require something to be read and written at the same time. Such things cannot happen if you cannot write.
Spending some time to search through the Java library for the class that fits your problem the best usually solves a lot of trouble and reduces the size of the code a lot.
Try to switch places of
while(!sharedList.isEmpty())
and
synchronized(sharedList)
I don't think you need synchronized on removeListElement().

Categories