Why do I get inconsistencies in this method when running - java

Sometimes the varible total will equal something else when run instead of 50005000 it's allways short like 50005001 when sometimes run why is this happening shouldn't synchronized(this) create a lock which can only be updated once the lock is released by the thread?
import java.util.concurrent.atomic.AtomicLong;
public class CurrentThread {
public static AtomicLong c = new AtomicLong(0L);
public static AtomicLong total = new AtomicLong(0L);
public static void main(String[] args) {
Thread t = Thread.currentThread();
System.out.println(t);
t.setName("My Thread");
System.out.println(t);
for (int x = 0; x < 10; x++) {
System.out.println("Instance " + x);
new Thread(new Updater(x, "Thread: " + String.valueOf(x))).start();
}
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
}
}
class Updater implements Runnable {
public int na;
private String threadName;
public Updater(int n, String threadName) {
this.na = n;
this.threadName = threadName;
}
#Override
public void run() {
this.updateCount();
if(CurrentThread.total.get() == 50005000) {
System.out.println("Passed");
}
else {
System.out.println("Failed");
}
}
public void updateCount() {
while (CurrentThread.c.get() < 10000) {
synchronized(this) {
CurrentThread.c.getAndIncrement();
CurrentThread.total.addAndGet(CurrentThread.c.get());
System.out.println(this.threadName + " " + String.valueOf(CurrentThread.c.get()) + " " + CurrentThread.total.get() + " " + System.nanoTime());
}
}
}
}

You're synchronizing on this, which is effectively not synchronizing at all, since each thread has a different Runnable instance.
Synchronize on something shared between all Updater instances instead, e.g. Updater.class.
Note, however, that synchronizing on AtomicLong is a bit of a code smell - it's meant to do things atomically already.
You can use compareAndSet instead, and avoid synchronizing entirely, e.g.:
while (CurrentThread.c.get() < 10000) {
while (true) {
long currValue = CurrentThread.c.get();
if (currValue >= 10000) break;
long newValue = currValue + 1;
// Only sets c to newValue if its value is still currValue.
if (CurrentThread.c.compareAndSet(currValue, newValue)) {
long total = CurrentThread.total.addAndGet(newValue);
System.out.println(
this.threadName + " " + newValue + " " + total + " " + System.nanoTime());
break;
}
}
}
Note that this makes use of "known" values, like newValue and total, rather than getting them again from the AtomicLong.

Related

How to perform multiple simultaneous actions in one thread?

I need ships to load and unload cargo at the same time.
Is there a way to do that in java?
I managed to make multiple ships work in port at the same time, but they first unload cargo and then load new crates.
That is my variant of Ship class
public class Ship implements Runnable {
String name;
Port port;
Queue<Goods> storage;
Pier pier;
int capacity;
int numOnBoard;
public Ship(String name, Port port, int capacity) {
this.name = name;
this.port = port;
storage = new LinkedBlockingDeque<>(capacity);
this.capacity = capacity;
int num=(int)(Math.random()*capacity);
numOnBoard=num;
for (int i = 0; i < num; i++) {
storage.add(new Goods());
}
}
public void run() {
try {
int unl = 0;
int l = 0;
pier = port.getPier();
System.out.println("Ship " + name + " taken " + pier.name);
while (unload()) {
if(unl>=numOnBoard) break;
unl++;
System.out.println("Ship " + name + " unloaded cargo.");
Thread.sleep(new Random(100).nextInt(500));
}
System.out.println("Ship " + name + " unloaded " + unl + " crates.");
Thread.sleep(100);
while (load()) {
l++;
System.out.println("Ship " + name + " loaded cargo.");
Thread.sleep(new Random(100).nextInt(500));
}
System.out.println("Ship " + name + " loaded " + l + " crates.");
port.releasePier(pier);
System.out.println("Ship " + name + " released " + pier.name);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private boolean unload() {
if (storage.size() <= 0) return false;
return port.addGoods(storage.poll());
}
private boolean load() {
if (storage.size() >= capacity) return false;
return port.takeGoods(storage,numOnBoard);
}
}
And the Port
public class Port {
Queue<Pier> piers;
Queue<Goods> goods;
int capacity;
public Port(int pierCount, int capacity) {
goods = new LinkedBlockingDeque<>(capacity);
piers = new LinkedBlockingDeque<>(pierCount);
this.capacity = capacity;
for (int i = 0; i < pierCount; i++)
piers.add(new Pier("Pier " + (i + 1)));
int num=(int)(Math.random()*capacity);
for (int i = 0; i < num; i++) {
goods.add(new Goods());
}
}
public boolean addGoods(Goods item) {
if (goods.size() >= capacity) return false;
return goods.add(item);
}
public boolean takeGoods(Queue<Goods> storage, int wasOnBoard) {
if (goods.size() <= wasOnBoard) return false;
return storage.add(goods.poll());
}
public Pier getPier() {
Pier taken = piers.poll();
while (taken == null) {
try {
System.out.println("There aren't any free piers. Waiting...");
Thread.sleep(1000);
taken = piers.poll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return taken;
}
public void releasePier(Pier pier) {
piers.add(pier);
}
public static void main(String[] args) {
Port port = new Port(4, 50);
ArrayList<Thread> ships = new ArrayList<>();
for (int i = 0; i < 5; i++) {
ships.add(new Thread(new Ship("ship " + (i+1), port, 30)));
}
for (Thread t : ships)
t.start();
}
}
I need each ship to load and unload cargo at the same time
What you're trying to accomplish within a single thread is exactly what multiple threads are for. Multi-threading enables you to write in a way where multiple activities can proceed concurrently in the same program:
A multi-threaded program contains two or more parts that can run concurrently and each part can handle a different task at the same time making optimal use of the available resources specially when your computer has multiple CPUs.
By definition, multitasking is when multiple processes share common
processing resources such as a CPU. Multi-threading extends the idea
of multitasking into applications where you can subdivide specific
operations within a single application into individual threads. Each
of the threads can run in parallel. The OS divides processing time not
only among different applications, but also among each thread within
an application.
Read more about Java multi-threading here.

Java thread not responding to volatile boolean flag

I am new to Java concurrency, and I met a very strange problem:
I read from a large file and used several worker threads to work on the input (some complicated string matching tasks). I used a LinkedBlockingQueue to transmit the data to the worker threads, and a volatile boolean flag in the worker class to respond to the signal when the end-of-file is reached.
However, I cannot get the worker thread to stop properly. The CPU usage by this program is almost zero in the end, but the program won't terminate normally.
The simplified code is below. I have removed the real code and replaced them with a simple word counter. But the effect is the same. The worker thread won't terminate after the whole file is processed, and the boolean flag is set to true in the main thread.
The class with main
public class MultiThreadTestEntry
{
private static String inputFileLocation = "someFile";
private static int numbOfThread = 3;
public static void main(String[] args)
{
int i = 0;
Worker[] workers = new Worker[numbOfThread];
Scanner input = GetIO.getTextInput(inputFileLocation);
String temp = null;
ExecutorService es = Executors.newFixedThreadPool(numbOfThread);
LinkedBlockingQueue<String> dataQueue = new LinkedBlockingQueue<String>(1024);
for(i = 0 ; i < numbOfThread ; i ++)
{
workers[i] = new Worker(dataQueue);
workers[i].setIsDone(false);
es.execute(workers[i]);
}
try
{
while(input.hasNext())
{
temp = input.nextLine().trim();
dataQueue.put(temp);
}
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
input.close();
for(i = 0 ; i < numbOfThread ; i ++)
{
workers[i].setIsDone(true);
}
es.shutdown();
try
{
es.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
The worker class
public class Worker implements Runnable
{
private LinkedBlockingQueue<String> dataQueue = null;
private volatile boolean isDone = false;
public Worker(LinkedBlockingQueue<String> dataQueue)
{
this.dataQueue = dataQueue;
}
#Override
public void run()
{
String temp = null;
long count = 0;
System.out.println(Thread.currentThread().getName() + " running...");
try
{
while(!isDone || !dataQueue.isEmpty())
{
temp = dataQueue.take();
count = temp.length() + count;
if(count%1000 == 0)
{
System.out.println(Thread.currentThread().getName() + " : " + count);
}
}
System.out.println("Final result: " + Thread.currentThread().getName() + " : " + count);
}
catch (InterruptedException e)
{
}
}
public void setIsDone(boolean isDone)
{
this.isDone = isDone;
}
}
Any suggestions to why this happens?
Thank you very much.
As Dan Getz already said your worker take() waits until an element becomes available but the Queue may be empty.
In your code you check if the Queue is empty but nothing prevents the other Workers to read and remove an element from the element after the check.
If the Queue contains only one element and t1 and t2 are two Threads
the following could happen:
t2.isEmpty(); // -> false
t1.isEmpty(); // -> false
t2.take(); // now the queue is empty
t1.take(); // wait forever
in this case t1 would wait "forever".
You can avoid this by using pollinstead of take and check if the result is null
public void run()
{
String temp = null;
long count = 0;
System.out.println(Thread.currentThread().getName() + " running...");
try
{
while(!isDone || !dataQueue.isEmpty())
{
temp = dataQueue.poll(2, TimeUnit.SECONDS);
if (temp == null)
// re-check if this was really the last element
continue;
count = temp.length() + count;
if(count%1000 == 0)
{
System.out.println(Thread.currentThread().getName() + " : " + count);
}
}
System.out.println("Final result: " + Thread.currentThread().getName() + " : " + count);
}
catch (InterruptedException e)
{
// here it is important to restore the interrupted flag!
Thread.currentThread().interrupt();
}
}

implementing synchronization to get the proper threads output properly

Currently when I run the program, the threads are running at random. For example the current output is :
Global.sharedBuffer[0] = 2
Global.sharedBuffer[1] = 1
Global.sharedBuffer[2] = 1
Global.sharedBuffer[3] = 1
Global.sharedBuffer[4] = 1
Global.sharedBuffer[5] = 1
Global.sharedBuffer[6] = 1
Global.sharedBuffer[7] = 1
Global.sharedBuffer[8] = 1
Global.sharedBuffer[9] = 1
Global.sharedBuffer[10] = 2
Global.sharedBuffer[11] = 4
Global.sharedBuffer[12] = 3
What I want is from sharedBuffer 0 to 9 all 1's , then from 10 - 19 all 2's and etc. I added a synchronization block thinking it would do this, however, it just stopped it from context switching every time a thread was called. How do you go about implementing this?
CODE:
import java.io.*;
import java.lang.*;
import java.util.*;
class MyThreadExample2 {
public static void main(String[] args) {
HelloThread ht1 = new HelloThread(1);
HelloThread ht2 = new HelloThread(2);
HelloThread ht3 = new HelloThread(3);
HelloThread ht4 = new HelloThread(4);
ht1.start();
ht2.start();
ht3.start();
ht4.start();
}
}
class Global {
public static int[] sharedBuffer = new int[1000];
public static int in = 0;
}
class HelloThread extends Thread {
int threadID;
HelloThread(int threadID) {
System.out.println("threadID: " + threadID);
this.threadID = threadID;
}
public synchronized void run() {
for (int i = 0; i < 100; i++) {
if((Global.in >= 0 || Global.in <= 99) && (this.threadID == 1))
Global.sharedBuffer[Global.in] = this.threadID;
else if((Global.in >= 100 || Global.in <= 199) && (this.threadID == 2))
Global.sharedBuffer[Global.in] = this.threadID;
else if((Global.in >= 200 || Global.in <= 299) && (this.threadID == 3))
Global.sharedBuffer[Global.in] = this.threadID;
else if((Global.in >= 300 || Global.in <= 399) && (this.threadID == 4))
Global.sharedBuffer[Global.in] = this.threadID;
System.out.println("Thread " + this.threadID + " has written "
+ this.threadID + " to Global.sharedBuffer[" + Global.in + "]\n");
Global.in++;
}
if (this.threadID == 4)
{
try {this.sleep(2000L);
}
catch (Throwable e) {e.printStackTrace();
}
System.out.println("The final buffer is **************\n");
for (int i = 0; i < 30; i++) {
System.out.println("Global.sharedBuffer[" + i + "] = " +
Global.sharedBuffer[i]);
} // for
} // if
} // run
} // end Thread
Multi-threading only works if you can formulate tasks which can be performed independently of others. You have to avoid shared variables and if you can’t avoid it, the access must be properly guarded, which usually implies limiting the concurrency of the thread execution.
For your task it is simple to formulate independent tasks as each thread shall write into a different region of the array:
public class ThreadingExample {
public static void main(String[] args) {
final int numThread=4, chunkSize=10;
int[] array=new int[numThread*chunkSize];
Thread[] thread=new Thread[numThread];
// create threads and define their jobs
for(int t=0, p=0; t<numThread; t++, p+=chunkSize) {
thread[t]=new Thread(new FillInJob(array, t, p, chunkSize));
}
// start the threads
for(Thread t: thread) t.start();
// now all running concurrently
// wait for completion
try {
for(Thread t: thread) t.join();
} catch(InterruptedException ex) {
throw new AssertionError(ex);
}
// use result
System.out.println(java.util.Arrays.toString(array));
}
}
class FillInJob implements Runnable {
private final int[] targetArray;
private final int myID, startIndex, endIndex;
FillInJob(int[] target, int id, int start, int size) {
targetArray=target;
myID=id;
startIndex=start;
endIndex=start+size;
}
public void run() {
for(int ix=startIndex; ix<endIndex; ix++)
targetArray[ix]=myID;
}
}

How Can I remove an item from ConcurrentHashMap when no have a thread holding certain object anymore?

Supposing I have a temporary collection (ConcurrentHashMap) to hold a reference for a certain object, e.g., a HttpSession. While at least one thread is using a session (in the moment of a request), it can't be removed. But, when no more threads are using a session concurrently, it should be removed to release memory. I tried implement a example similar to that, but I got a NullPointerException. What I'm doing wrong? :(
class Elem {
// AtomicInteger saldo = new AtomicInteger(1000);
Integer saldo = 1000;
}
class Sum implements Runnable {
Map<String, Elem> saldos;
AtomicInteger n;
public Sum(Map<String, Elem> saldos, AtomicInteger n) {
this.saldos = saldos;
this.n = n;
}
#Override
public void run() {
Random rand = new Random();
int r = rand.nextInt(1000);
Elem e = this.saldos.get("saldo");
//Null Pointer Exception occurs here!
synchronized (e) {
this.n.incrementAndGet();
if (r % 2 == 0) {
Integer saldoLido = e.saldo;
e.saldo += r;
Integer saldoAtual = e.saldo;
System.out.println("saldo lido: " + saldoLido + " somado: " + r
+ " saldo atual: " + (saldoAtual) + " "
+ System.currentTimeMillis());
} else {
Integer saldoLido = e.saldo;
e.saldo -= r;
Integer saldoAtual = e.saldo;
System.out.println("saldo lido: " + saldoLido + " subtraído: "
+ r + " saldo atual: " + (saldoAtual) + " "
+ System.currentTimeMillis());
}
if(this.n.decrementAndGet() == 0)
this.saldos.remove("saldo");
}
}
}
public class Main {
public static void main(String[] args) throws Exception {
Map<String, Elem> saldos = new ConcurrentHashMap<>(20, 0.9f, 1);
AtomicInteger n = new AtomicInteger(0);
saldos.put("saldo", new Elem());
ExecutorService exec = Executors.newFixedThreadPool(20);
try {
for (int i = 0; i < 20; ++i)
exec.execute(new Sum(saldos, n));
exec.shutdown();
while (!exec.isTerminated()) {}
System.out.println("got elem: " + saldos.get("saldo") + " " + n);
} catch (Exception ex) {
exec.shutdownNow();
ex.printStackTrace();
}
}
}
I put together a working example for you that may help you with your issue. I made Main a junit test to make it easy to run in your favorite IDE or elsewhere.
A couple of points to note.
A CountDownLatch was added so that all threads would complete before the executor service was shutdown and the result printed out.
Elem uses an AtomicInteger so the synchronized block is no longer necessary.
The most important fix to the code was to increment the counter in the constructor of the Sum class so that the Elem wasn't removed from the map until each thread had a chance to process. Otherwise, it was possible for a thread to run all the way through and remove the Elem before other threads got a chance to execute.
-- Patrick
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
public class Main
{
#Test
public void testExecute() throws Exception
{
int threadCount = 20;
final CountDownLatch threadsCompleteLatch = new CountDownLatch( threadCount );
Map<String, Elem> saldos = new ConcurrentHashMap<>( threadCount, 0.9f, 1 );
AtomicInteger counter = new AtomicInteger( 0 );
Elem element = new Elem();
saldos.put( "saldo", element );
ExecutorService exec = Executors.newFixedThreadPool( threadCount );
try
{
for ( int i = 0; i < threadCount; ++i )
{
exec.execute( new Sum( threadsCompleteLatch, counter, saldos ) );
}
threadsCompleteLatch.await();
exec.shutdown();
System.out.println( "got elem: " + saldos.get( "saldo" ) + " counter: " + counter );
System.out.println( "resulting element: " + element );
}
catch ( Exception ex )
{
exec.shutdownNow();
ex.printStackTrace();
}
}
}
class Elem
{
private final AtomicInteger saldo = new AtomicInteger( 1000 );
public int add( int value )
{
return saldo.getAndAdd( value );
}
int getSaldo()
{
return saldo.get();
}
#Override
public String toString()
{
return "Elem{ " +
"saldo=" + saldo.get() +
" }";
}
}
class Sum implements Runnable
{
private final Random rand = new Random();
private final CountDownLatch latch;
private final AtomicInteger counter;
private final Map<String, Elem> saldos;
Sum( CountDownLatch latch, AtomicInteger counter, Map<String, Elem> saldos )
{
this.latch = latch;
this.saldos = saldos;
this.counter = counter;
counter.incrementAndGet();
}
#Override
public void run()
{
int randomValue = rand.nextInt( 1000 );
Elem element = saldos.get( "saldo" );
if ( randomValue % 2 != 0 )
{
randomValue = -randomValue;
}
int saldoLido = element.add( randomValue );
int saldoAtual = element.getSaldo();
System.out.println(
"saldo lido: " + saldoLido + " somado: " + randomValue + " saldo atual: " + (saldoAtual) + " " + System.currentTimeMillis() );
if ( counter.decrementAndGet() == 0 )
{
saldos.remove( "saldo" );
}
latch.countDown();
}
}
Throw it all away and use a java.util.WeakHashMap. It already does exactly what you're looking for.

How to create a cyclic exchange of three threads?

How to create a cyclic exchange of three threads? That is: first thread must send data to second, second to third and third thread must send data to first.
I wrote some code, but threads exchange in random oder.
class DataClass {
int value;
String message;
DataClass(int v, String s) {
value = v;
message = s;
}
int getValue() {
return (value);
}
String getMassage() {
return (message);
}
}
class Loop implements Runnable {
int counter;
String name;
Exchanger<DataClass> exchanger;
Loop(int startValue, String id, Exchanger<DataClass> ex) {
counter = startValue;
name = id;
exchanger = ex;
System.out.println(name + ": created");
}
public void run() {
System.out.println(name + ": started");
DataClass data = new DataClass(counter, name);
for (int i = 0; i < 3; ++i) {
try {
DataClass newData = exchanger.exchange(data);
counter += newData.getValue();
System.out.println(name + ": from "
+ newData.getMassage() + ": data: "
+ newData.getValue() + ": state = " + counter);
} catch (InterruptedException e) {
System.err.println(e.toString());
}
}
System.out.println(name + ": ended");
}
}
public class ExchangerDemo {
public static void main(String args[]) {
System.out.println("Main process started");
Exchanger<DataClass> exchanger = new Exchanger<DataClass>();
Loop loop1 = new Loop(1, "First", exchanger);
Loop loop2 = new Loop(2, "Second", exchanger);
Loop loop3 = new Loop(3, "Third", exchanger);
new Thread(loop1).start();
new Thread(loop2).start();
new Thread(loop3).start();
System.out.println("Main process ended");
}
}
For your dependency you should make three classes, and have three distinct Exchange objects (one in each). So thread1 would be between 1 and 2 (output of 1 to 2), thread 2's would be between 2 and 3 and thread 3's exhanger would be between itself and 1. Remember the exchanger's would guard only until it had its input from its feeder, to till it passes to its receiver.
Also synchronized is not as bad as the books make out. use it. Watch http://www.youtube.com/watch?v=WTVooKLLVT8
Also for reference Best way of running two threads alternatively?
Also why do you need three threads? Can you use a thread pool and have each task to the 3 things ?

Categories

Resources