Dining Philosopher Thread and Semaphore - java

I made a simple GUI that has 5 tables and forks and tried to visualize this famous problem, but I cannot achieve to fully implement. I didn't get the stuck point for my code, if anyone have suggestion for me to solve this problem, any help would be appreciated and thanks in advance!
Extra Note: There is also an error that i guess it is about my array creation ideas, i have an error as java.lang.ArrayIndexOutOfBoundsException: 5.
public class Philosopher implements Runnable {
private static Table table;
private int ID;
private int N = 5;
private static Semaphore s1 = new Semaphore(1) ;
private static Semaphore[] sarray = new Semaphore[5];
private int[] array = new int[5];
private int thinking = 0;
private int hungry = 1;
private int eating = 2;
private int left = (ID + N - 1) % N;
private int right = (ID + 1) % N;
void test(int i)
{
if((array[i] == hungry) && (array[left] != eating) && (array[right] != eating))
{
table.ForkTake_GUI(i);
array[i] = eating;
sarray[i].release();
}
}
void take_forks(int i)
{
try {
s1.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
array[i] = hungry;
table.Hungry_GUI(i);
test(i);
s1.release();
table.Eating_GUI(i);
sarray[i].release();
}
void put_forks(int i)
{
table.StopEating_GUI(i);
try {
s1.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
array[i] = thinking;
test(left);
test(right);
table.ForkPut_GUI(i);
s1.release();
}
public Philosopher(int i)
{
setID(i);
}
public void run()
{
while(true)
{
Random RandomGenerator = new Random();
int randomNum = RandomGenerator.nextInt(10);
try {
Thread.sleep((randomNum * 1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
take_forks(ID);
//table.Eating_GUI();
put_forks(ID);
}
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
table = new Table();
table.frame.setVisible(true);
}
catch(Exception e){
e.printStackTrace();
}
}
});
Philosopher p1 = new Philosopher(1);
Philosopher p2 = new Philosopher(2);
Philosopher p3 = new Philosopher(3);
Philosopher p4 = new Philosopher(4);
Philosopher p5 = new Philosopher(5);
Thread pt1 = new Thread(p1);
Thread pt2 = new Thread(p2);
Thread pt3 = new Thread(p3);
Thread pt4 = new Thread(p4);
Thread pt5 = new Thread(p5);
sarray[0] = new Semaphore(1);
sarray[1] = new Semaphore(1);
sarray[2] = new Semaphore(1);
sarray[3] = new Semaphore(1);
sarray[4] = new Semaphore(1);
pt1.start();
pt2.start();
pt3.start();
pt4.start();
pt5.start();
}
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
}

Take a look at where you acquire a mutex from sarray - point is that you don't, so at least there's redundant code in there.
Further notes:
You define N but use the magic number 5 all over.
You seem to have one "central" mutex and one for each fork. Using a central mutex would already solve the original problem.
Consider putting each mutex and the data it protects into an aggregate. That would make it clear that the five mutexes are for the five forks and not for the five philosophers, or?
Your out-of-bounds is obviously caused by a shift between 1-base and 0-based indices. Could that be caused by changing ID after computing left and right? In general, I wouldn't store these as members. Also, be aware that the values you have there are for the philosophers, not for the forks! Draw a picture, that will help you get those right!

Related

Getting IllegalMonitorStateException while Using wait() and Notify() to perform inter thread communication between 4 thread

I want to run a thread only when the next turn is equal to current thread for example if nextTurn = 3 then only the thread which is created for player 3 should run and others should wait state. and same for other thread the below program keeps on changing the turn for infinite times so i want a thread specific to the turn should run infinite time.
import static java.util.Collections.shuffle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class DemoMain {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
int sizeOfDeck = 31;
System.out.println("Enter cards in the Deck");
ArrayList<Integer> cardNumber = new ArrayList<Integer>(sizeOfDeck);
// for (int i = 0; i <= sizeOfDeck; i++) {
// Scanner input = new Scanner(System.in);
// cardNumber.add(input.nextInt());
// }
for(int i=0 ; i<=31;i++)
{
cardNumber.add(i);
}
System.out.println("Cards: "+ cardNumber );
shuffle(cardNumber);
List<Integer> Piles1 = cardNumber.subList(0, 4);
List<Integer> Piles2 = cardNumber.subList(4, 8);
List<Integer> Piles3 = cardNumber.subList(8, 12);
List<Integer> Piles4 = cardNumber.subList(12, 16);
List<Integer> player1Card = cardNumber.subList(16, 20);
List<Integer> player2Card = cardNumber.subList(20, 24);
List<Integer> player3Card = cardNumber.subList(24, 28);
List<Integer> player4Card = cardNumber.subList(28, 32);
Map<Integer, Integer> player1Map = getPlayerCards(player1Card);
Map<Integer, Integer> player2Map = getPlayerCards(player2Card);
Map<Integer, Integer> player3Map = getPlayerCards(player3Card);
Map<Integer, Integer> player4Map = getPlayerCards(player4Card);
Player p1 = new Player(player1Map, Piles1, Piles2, "Player1");
Player p2 = new Player(player2Map, Piles2, Piles3, "Player2");
Player p3 = new Player(player3Map, Piles3, Piles4, "Player3");
Player p4 = new Player(player4Map, Piles4, Piles1, "Player4");
p1.start();
p2.start();
p3.start();
p4.start();
}
private static Map<Integer, Integer> getPlayerCards(List<Integer> playerCard) {
Map<Integer, Integer> cardsMap = null;
for (Integer card : playerCard) {
if (cardsMap == null) {
cardsMap = new HashMap<Integer, Integer>();
}
Integer count = cardsMap.get(card);
if (count == null) {
cardsMap.put(card, 1);
} else {
cardsMap.put(card, cardsMap.get(card) + 1);
}
}
return cardsMap;
}
}
Player.java
import java.util.List;
import java.util.Map;
public class Player extends Thread {
private Map<Integer, Integer> holdings;
private List<Integer> deckToUseToDraw;
private List<Integer> deckToUseForDiscard;
private Integer currentlyDrawnCard;
private String playerTrun;
private boolean hasWon = false;
//static String Nextturn = "Player1";
StringBuffer Nextturn = new StringBuffer("Player1");
public Player(Map<Integer, Integer>holdings, List<Integer> drawDeck, List<Integer> discardDeck, String playerTurn) {
this.holdings = holdings;
this.deckToUseToDraw = drawDeck;
this.deckToUseForDiscard = discardDeck;
this.playerTrun = playerTurn;
}
public void run() {
try {
playNew();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void playNew() throws InterruptedException {
synchronized (Nextturn) {
while(true) {
if (! playerTrun.equalsIgnoreCase(String.valueOf(Nextturn))) {
try {
System.out.println("waiting: "+ playerTrun);
Nextturn.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("Running: "+playerTrun);
nextTurn();
Nextturn.notifyAll();
}
}
}
}
public void nextTurn()
{
if(playerTrun.equalsIgnoreCase("Player1"))
Nextturn = new StringBuffer("Player2");
else if(playerTrun.equalsIgnoreCase("Player2"))
Nextturn = new StringBuffer("Player3");
else if(playerTrun.equalsIgnoreCase("Player3"))
Nextturn = new StringBuffer("Player4");
else if(playerTrun.equalsIgnoreCase("Player4"))
Nextturn = new StringBuffer("Player1");
}
}
To use wait()/notify() on an object, the thread has to own the monitor on that object.
Since you create a new StringBuffer instance and assign it to Nextturn meanwhile the thread owns the monitor :
Nextturn = new StringBuffer("Player1");
I suppose that the current thread loses the monitor or at least doesn't have the monitor on the new object. So you cannot any longer invoke wait()/notify() on Nextturn.
For example here :
nextTurn(); // you assign the variable to a new object
Nextturn.notifyAll(); // but you notify on that new object
As alternative, use a simple object to represent the lock for the turn and a String to represent the current player :
final Object lockOnTurn = new Object();
String currentPlayer = "...";
// ..
private void playNew() throws InterruptedException {
synchronized (lockOnTurn) {
while(true) {
if (! playerTrun.equalsIgnoreCase(String.valueOf(currentPlayer))) {
try {
System.out.println("waiting: "+ playerTrun);
lockOnTurn.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("Running: "+playerTrun);
currentPlayer = nextTurn();
lockOnTurn.notifyAll();
}
}
}
}

How to consume in Producer-Consumer using Semphores?

I am trying out the Producer-Consumer problem using Semaphore. The program looks fine to me except for one place.
public class ProducerConsumerWithSemaphores
{
private final ArrayList<Integer> list = new ArrayList<>(5);
private final Semaphore semaphoreProducer = new Semaphore(1);
private final Semaphore semaphoreConsumer = new Semaphore(0);
private void produce() throws InterruptedException
{
for(int i = 0;i< 5;i++)
{
semaphoreProducer.acquire();
list.add(i);
System.out.println("Produced: " + i);
semaphoreConsumer.release();
}
}
private void consumer() throws InterruptedException
{
while (!list.isEmpty()) /// This line is where I have the doubt
{
semaphoreConsumer.acquire();
System.out.println("Consumer: " + list.remove(list.size()-1));
semaphoreProducer.release();
Thread.sleep(100);
}
}
public static void main(String[] args)
{
final ProducerConsumerWithSemaphores obj = new ProducerConsumerWithSemaphores();
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
obj.produce();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
obj.consumer();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}).start();
}
}
Is it okay to check the list if it is not empty before acquiring the semaphore? Will this cause any problem in multithreaded environment?
private void consumer() throws InterruptedException
{
while (!list.isEmpty()) /// This line is where I have the doubt
The problem is, if consumer runs faster than producer, your consumer quit immediately, then you have no consumer!!
The correct example looks like,
Producer–consumer problem#Using semaphores. I believe your intention is not to use true as endless loop because you want Producer/Consumer to quit when job is done. If that's your intention, you can 1. set a totalCount to end the loop. 2. Or a boolean flag which will be set by producer after putItemIntoBuffer when producer put the last one. The flag must be protected as well as the buffer.(update: this method doesn't work if there's multiple producers/consumers) 3. Simulate EOF ( idea taken from producer - consume; how does the consumer stop?)
Will this cause any problem in multithreaded environment?
Your critical section (your list) is not protected . Usually we use 3 semaphores. The 3rd one is used as a mutex to protect the buffer.
To stop producers/consumers,
Example code with method 1:
public class Test3 {
private Semaphore mutex = new Semaphore(1);
private Semaphore fillCount = new Semaphore(0);
private Semaphore emptyCount = new Semaphore(3);
private final List<Integer> list = new ArrayList<>();
class Producer implements Runnable {
private final int totalTasks;
Producer(int totalTasks) {
this.totalTasks = totalTasks;
}
#Override
public void run() {
try {
for (int i = 0; i < totalTasks; i++) {
emptyCount.acquire();
mutex.acquire();
list.add(i);
System.out.println("Produced: " + i);
mutex.release();
fillCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
private final int totalTasks;
Consumer(int totalTasks) {
this.totalTasks = totalTasks;
}
#Override
public void run() {
try {
for (int i = 0; i < totalTasks; i++) {
fillCount.acquire();
mutex.acquire();
int item = list.remove(list.size() - 1);
System.out.println("Consumed: " + item);
mutex.release();
emptyCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void runTest() {
int numProducer = 3;
int tasksPerProducer = 10;
int numConsumer = 6;
int tasksPerConsumer = 5;
for (int i = 0; i < numProducer; i++) {
new Thread(new Producer(tasksPerProducer)).start();
}
for (int i = 0; i < numConsumer; i++) {
new Thread(new Consumer(tasksPerConsumer)).start();
}
}
public static void main(String[] args) throws IOException {
Test3 t = new Test3();
t.runTest();
}
}
Example code with method 3:
public class Test4 {
private Semaphore mutex = new Semaphore(1);
private Semaphore fillCount = new Semaphore(0);
private Semaphore emptyCount = new Semaphore(3);
private Integer EOF = Integer.MAX_VALUE;
private final Queue<Integer> list = new LinkedList<>(); // need to put/get data in FIFO
class Producer implements Runnable {
private final int totalTasks;
Producer(int totalTasks) {
this.totalTasks = totalTasks;
}
#Override
public void run() {
try {
for (int i = 0; i < totalTasks + 1; i++) {
emptyCount.acquire();
mutex.acquire();
if (i == totalTasks) {
list.offer(EOF);
} else {
// add a valid value
list.offer(i);
System.out.println("Produced: " + i);
}
mutex.release();
fillCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
#Override
public void run() {
try {
boolean finished = false;
while (!finished) {
fillCount.acquire();
mutex.acquire();
int item = list.poll();
if (EOF.equals(item)) {
// do not consume this item because it means EOF
finished = true;
} else {
// it's a valid value, consume it.
System.out.println("Consumed: " + item);
}
mutex.release();
emptyCount.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void runTest() {
int numProducer = 3;
int tasksPerProducer = 10;
for (int i = 0; i < numProducer; i++) {
new Thread(new Producer(tasksPerProducer)).start();
}
int numConsumer = numProducer; // producers will put N EOFs to kill N consumers.
for (int i = 0; i < numConsumer; i++) {
new Thread(new Consumer()).start();
}
}
public static void main(String[] args) throws IOException {
Test4 t = new Test4();
t.runTest();
}
}
Instead of using two semaphores why dont you use a single semaphore to such that the synchronization is made between threads link
Additional you can use ArrayBlockingQueue which are thread safe to properly demonstrate the Producer Consumer Problem.

Sequence number using thread Synchronization

I want to print a series of 1 to 100 number using n number of threads (lets take 10 threads for this). Condition is 1st thread will have a sequence number from 1, 11,21....91, 2nd thread will have a sequence 2,12,22.....92 and so on. All other threads will have a sequence number like that. Now I want to print number in sequence 1 to 100. I know we can use synchronization, wait and notify method and using a variable or flag counter but I don't think this is a good idea to use it. I want to use without concurrency (like executors etc) how will I do that. Please suggest.
public class PrintNumberSequenceUsingRunnable {
int notifyValue = 1;
public static void main(String[] args) {
PrintNumberSequenceUsingRunnable sequence = new PrintNumberSequenceUsingRunnable();
Thread f = new Thread(new First(sequence), "Fisrt");
Thread s = new Thread(new Second(sequence), "Second");
Thread t = new Thread(new Third(sequence), "Third");
f.start();
s.start();
t.start();
}
}
class First implements Runnable {
PrintNumberSequenceUsingRunnable sequence;
public First(PrintNumberSequenceUsingRunnable sequence) {
this.sequence = sequence;
}
#Override
public void run() {
printFist();
}
private void printFist() {
synchronized (sequence) {
for (int i = 1; i <= 20; i += 3) {
while (sequence.notifyValue != 1) {
try {
sequence.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + i);
sequence.notifyValue = 2;
sequence.notifyAll();
}
}
}
}
class Second implements Runnable {
PrintNumberSequenceUsingRunnable sequence;
public Second(PrintNumberSequenceUsingRunnable sequence) {
this.sequence = sequence;
}
#Override
public void run() {
printSecond();
}
private void printSecond() {
synchronized (sequence) {
for (int i = 2; i <= 20; i += 3) {
while (sequence.notifyValue != 2) {
try {
sequence.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + i);
sequence.notifyValue = 3;
sequence.notifyAll();
}
}
}
}
class Third implements Runnable {
PrintNumberSequenceUsingRunnable sequence;
public Third(PrintNumberSequenceUsingRunnable sequence) {
this.sequence = sequence;
}
#Override
public void run() {
printThrid();
}
private void printThrid() {
synchronized (sequence) {
for (int i = 3; i <= 20; i += 3) {
while (sequence.notifyValue != 3) {
try {
sequence.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " + i);
sequence.notifyValue = 1;
sequence.notifyAll();
}
}
}
}
You need to have values sorted on each threads. Each time a thread writes a number, it triggers an event in an event bus. All threads are subscribed to the event.
You start the system by triggering the event [minimum value - 1].
Each thread will receive a notification that the value [minimum value - 1] has been published. Only the thread that has the value [minimum value] will act and will trigger a new event for value [minimum value + 1].
Edit: I haven't tested it, but something like this.
static void main(String[] args) {
List<Deque<Integer>> publishQueues = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
new Thread(new Worker(i, publishQueues)).start();
}
}
class Worker implements Runnable {
Deque subscriberQueue;
List<Deque<Integer>> publishQueues;
int i;
Worker(int i, List<Deque<Integer>> publishQueues) {
this.i = i;
this.publishQueues = publishQueues;
this.subscriberQueue = new ConcurrentLinkedDeque<>();
this.publishQueues.add(this.subscriberQueue);
}
void Run() {
LinkedList<Integer> ints = new LinkedList<>();
for (int j = i; j <= 100; j+=10) {
ints.add(j);
}
while (true) {
Integer publishedInteger = subscriberQueue.poll();
if (publishedInteger == ints.getFirst() - 1) {
Integer integer = ints.poll();
System.out.println(integer);
for (Dequeu<Integer> publishQueue : publishQueues) {
publishQueue.addLast(integer);
}
}
}
}
}

Huge delay when socketing in java

(UPDATED CODE)
I'm trying to make clients communicate with server (I've made simple client-server apps, like a chatroom). The communication is created, but there is a huge delay (I send coordinates from the client to the server). It's over 10 seconds (sometimes even more). What could be the problem?
The client:
public class GameComponent extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private static final int WIDTH = 320;
private static final int HEIGHT = 240;
private static final int SCALE = 2;
private boolean running;
private JFrame frame;
Thread thread;
public static final int GRID_W = 16;
public static final int GRID_H = 16;
private Socket socket;
private DataInputStream reader;
private DataOutputStream writer;
private HashMap<Integer, OtherPlayer> oPlayers;
private ArrayList<OtherPlayer> opList;
private int maxID = 1;
private int ID;
Player player;
public GameComponent() {
//GUI code..
oPlayers = new HashMap<Integer, OtherPlayer>(); //Hash map to be able to get players by their ID's
opList = new ArrayList<OtherPlayer>(); //And an array list for easier drawing
setUpNetworking();
start();
}
public void start() {
if (running)
return;
running = true;
thread = new Thread(this);
player = new Player(GRID_W * 2, GRID_H * 2);
thread.start();
}
public void stop() {
if (!running)
return;
running = false;
}
public void run() { //The main loop, ticks 60 times every second
long lastTime = System.nanoTime();
double nsPerTick = 1000000000D / 60D;
int frames = 0;
int ticks = 0;
long lastTimer = System.currentTimeMillis();
double delta = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / nsPerTick;
lastTime = now;
boolean shouldRender = true;
while (delta >= 1) {
ticks++;
tick(delta);
delta -= 1;
shouldRender = true;
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (shouldRender) {
frames++;
render();
}
if (System.currentTimeMillis() - lastTimer >= 1000) {
lastTimer += 1000;
frames = 0;
ticks = 0;
}
}
}
private void tick(double delta) { //main logic
player.move();
try {
writer.writeInt(ID); //I send the player data here (id, x, y)
writer.writeInt(player.getX());
writer.writeInt(player.getY());
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void render(Graphics2D g2d) {
//rendering the stuff
for (OtherPlayer i : opList) { //drawing a black rectangle for every other player
g2d.fillRect(i.getX(), i.getY(), GRID_W, GRID_H);
}
}
private void render() {
//more rendering...
}
public static void main(String[] args) {
new GameComponent();
}
class TKeyListener implements KeyListener {
//movement methods...
}
private void setUpNetworking() { //This is where I make my message reader and data IO
try {
socket = new Socket("127.0.0.1", 5099);
reader = new DataInputStream(socket.getInputStream());
writer = new DataOutputStream(socket.getOutputStream());
Thread rT = new Thread(new msgReader());
rT.start();
} catch (Exception e) {
e.printStackTrace();
}
}
class msgReader implements Runnable { //where I read messages
public void run() {
try {
ID = reader.readInt(); //when I connect, I get an id from the server
while(true) { //my main loop
int oid = reader.readInt(); //get the read data id
int ox, oy;
ox = reader.readInt(); //get the read player's x and y
oy = reader.readInt();
if (oid != ID){ //If not reading myself
if (oPlayers.containsKey(oid)) { //If a player with this id exists
OtherPlayer op = (OtherPlayer) oPlayers.get(oid);
op.setX(ox); //set it's x, y
op.setY(oy);
} else { //if it doesn't exist, create him
OtherPlayer op = new OtherPlayer(ox, oy);
opList.add(op);
oPlayers.put(oid, op);
}
}
maxID = reader.readInt(); //Allways read the highest current id from server
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
And the server:
public class ServerBase {
ServerSocket serverSocket;
ArrayList<DataOutputStream> clients;
private int id = 1;
SyncSend ss = new SyncSend();
class ClientHandler implements Runnable {
private Socket soc;
private DataInputStream reader;
private int x;
private int y;
private int id;
private boolean run = true;
public ClientHandler(Socket s) {
soc = s;
try {
reader = new DataInputStream(soc.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while (run) {
id = reader.readInt();
x = reader.readInt();
y = reader.readInt();
if (id == 2)
System.out.println("x: " + x + " y: " + y);
int[] tmb = {id, x, y};
ss.sendEveryone(tmb);
}
} catch (Exception e) {
run = false;
clients.remove(this);
}
}
}
class SyncSend {
public synchronized void sendEveryone(int[] a) throws SocketException {
ArrayList<DataOutputStream> cl = (ArrayList<DataOutputStream>) clients.clone();
Iterator<DataOutputStream> it = cl.iterator();
while(it.hasNext()){
try {
DataOutputStream writer = (DataOutputStream) it.next();
writer.writeInt(a[0]);
writer.writeInt(a[1]);
writer.writeInt(a[2]);
writer.writeInt(id-1);
writer.flush();
} catch (Exception ex) {
throw new SocketException();
}
}
}
}
public void init() {
clients = new ArrayList<DataOutputStream>();
try {
serverSocket = new ServerSocket(5099);
while(true) {
Socket clientSocket = serverSocket.accept();
DataOutputStream clientWriter = new DataOutputStream(clientSocket.getOutputStream());
clients.add(clientWriter);
clientWriter.writeInt(id);
id++;
Thread t = new Thread(new ClientHandler(clientSocket));
t.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new ServerBase().init();
}
}
What causes the delay? I've been searching for the reason for hours now, but with no success.
You most likely need to call flush() on the client-side. Even if this is not your current problem, it is probably a good idea.
Streams may buffer their content, meaning they may not send the data to its destination (whether that be a disk or over the wire to a server) the instant you call write (or writeInt in this case). Instead, they may wait until they get a sufficient amount of data to make the transfer "worth it". If they did not behave in this way, they would end up making lots of inefficient, smaller transfers. The downside to all of this is that you may need to call flush to tell the stream that you are done sending data for a while and that the stream should go ahead and initiate the transfer.
try to put your codes into several threads everywhere you can and then call threads, I mean you don't need to wait for every Socket and simply run all of them at same time...or something like this :)
for example in Port Scanners, you should use many threads to speed up searching...
Be aware that your call to ss.sendEveryone(tmb) is synchronized on the ss object. I am assuming this is a static variable somewhere that holds a reference to all of the clients. This means that if there are several clients sending data at the same time, a lot of calls to sendEveryone will happen all at once and they will all line up in a queue waiting for the others to finish, before those threads can go back and read more data from the client again.
As a diagnostic exercise, you may want to remove this call and see if you still have your problem.

Parallel task with synchronized arraylist

My homework was to create project using parallelization that all should be proper.
However, I made my project but my profesor mentioned something is wrong in my code "please look at array list, something is not ok, maybe synchronization?".
I would like ask you community to help me and point what could be wrong. I think it might be problem with not covering by synchronize brackets my array list, am I right?
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* My project finds all dividors for specific number
*It must use threads, so I made them. First I start them (first loop)
*then join them (second loop). My project must have that loops.
*Problem might be with not synchronizing methods array list...
*/
public class Main {
private final static int NUMBER = 100;
private final static List<Integer> dividors = new ArrayList<Integer>();
public static void main(String[] args) {
new Main().doStuff();
}
private int sqr;
private int sqrp1;
private void doStuff() {
sqr = (int) Math.sqrt(NUMBER);
sqrp1 = sqr + 1;
Thread[] t = new Thread[sqrp1];
//starting tasks
for (int i = 1; i < sqrp1; i++) {
final int it = i;
if (NUMBER % i == 0) {
final int e = i;
t[i] = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("sta"+e);
if (!checkContains(e)) {
addElement(e);
}
final int dividednumber = NUMBER / e;
if (!checkContains(dividednumber)) {
addElement(dividednumber);
}
}
});
t[i].start();
}
}
//calling join for tasks
for (int i = 1; i < sqrp1; i++) {
final int it = i;
if (NUMBER % i == 0) {
try {
System.out.println("sto"+i);
t[i].join();
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
System.out.println("xxx");
Collections.sort(dividors);
Integer[] arrayDividors = dividors.toArray(new Integer[0]);
for (int i = 0; i < arrayDividors.length; i++) {
System.out.println(arrayDividors[i]);
}
}
private synchronized void addElement(int element) {
dividors.add(element);
}
private synchronized boolean checkContains(int element) {
return dividors.contains(element);
}
}
Am I right changing this part, is it ok now?
t[i] = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("waiting " + e);
synchronized (this) {
System.out.println("entering " + e);
if (!checkContains(e)) {
addElement(e);
}
final int dividednumber = NUMBER / e;
if (!checkContains(dividednumber)) {
addElement(dividednumber);
}
System.out.println("leaving " + e);
}
}
});
You need to turn this into a single atomic operation.
if (!checkContains(dividednumber)) {
addElement(dividednumber);
}
Imagine you have two threads.
T1: if (!checkContains(dividednumber)) { // false
T2: if (!checkContains(dividednumber)) { // false
T1: addElement(dividednumber); // adds number
T2: addElement(dividednumber); // adds same number
If you have one addElementWithoutDuplicates, this won't happen.

Categories