Thread can't read instances that are being modified by other threads - java

This scheme shows the functions that are being discussed below...
The OrderBook class looks like this:
public class OrderBook {
private TreeMap<Double, Double> bids;
private TreeMap<Double, Double> asks;
private Entry<Double, Double> bestBid;
private Entry<Double, Double> bestAsk;
public OrderBook() {
this.bids = new TreeMap<>();
this.asks = new TreeMap<>();
}
// Getters and setters...
// Example function that modifies its variables...
public void updateBids(double bidPrice, double bidVol) {
if(this.getBids().containsKey(bidPrice)) {
if(bidVol == 0.0) {
//System.out.println("Vol. 0: " + bidPrice + " - " + bidVol);
this.getBids().remove(bidPrice);
}
else if(bidVol > 0.0) {
//System.out.println("Actualizar Vol.: " + bidPrice + " - " + bidVol);
this.getBids().replace(bidPrice, bidVol);
}
else {
//System.out.println("Error. Unexpected volume:" +
// bidPrice + " - " + vol);
}
}
else {
// ...
}
this.setBestBid(this.getBids().lastEntry());
}
}
Client 1 class and Client 2 class are different from each other (they perform different write operations over the their OrderBook class) and they are launched from different threads. A Client class looks like this:
public class Client1 extends WebSocketClient {
private OrderBook ob;
public Client1(URI serverURI, OrderBook ob) {
super(serverURI);
this.ob = ob;
}
// Extended class implementations...
#Override
public void onMessage(String message) {
parse(message);
}
private void parse(String msg) {
JSONObject json = new JSONObject(msg);
if(json.has("b")) {
double b = json.getDouble("b");
double a = json.getDouble("a");
double B = json.getDouble("B");
double A = json.getDouble("A");
/**
* HERE performs the modification of the OrderBook class passed in the
* constructor. I don't know if this synchronized block is needed...
*/
synchronized(this.ob) {
this.ob.setBestBid(new AbstractMap.SimpleEntry<>(bidPrice, bidVol));
this.ob.setBestAsk(new AbstractMap.SimpleEntry<>(askPrice, askVol));
}
}
}
}
The problem comes when in the Main class (launched in another thread), I try to read the updated instances of the class OrderBook that are being modified by the Client x classes...
Main class looks like this...
public class Main implements Runnable {
private OrderBook ob1;
private OrderBook ob2;
public Oportunity(OrderBook ob1, OrderBook ob2) throws URISyntaxException {
this.ob1 = ob1;
this.ob2 = ob2;
}
#Override
public void run() {
while(true) {
// PROBLEM HERE: doesn't show anything...
System.out.println(this.ob1.getLasValue());
System.out.println(this.ob2.getLasValue());
}
}
public static void main(String[] args) throws Throwable {
OrderBook ob1 = new OrderBook();
OrderBook ob2 = new OrderBook();
Thread client1 = new Thread(new Client1(new URI("..."), ob1));
Thread client2 = new Thread(new Client2(new URI("..."), ob2));
Thread m = new Thread(new Main(ob1, ob2));
client1.start();
client2.start();
m.start();
}
}
QUESTIONS:
How could I access consistently the last updated values of both instances of OrderBook?
Also, is it possible to show priority on write operations over read operations?

Your resource should be protected by a Lock.
Your synchronized block is useless, you should protect OrderBook methods.
synchronized keyword is used to protect resources.
public class CriticalData {
private int sum = 0;
public void synchronized add() {
this.setSum(this.getSum() + 1);
}
// Synchronized Getters & setters
}
#Test
public void multiThreadedAddition() {
// GIVEN
ExecutorService service = Executors.newFixedThreadPool(3);
CriticalData data = new CriticalData();
// WHEN
IntStream.range(0, 1000)
.forEach(count -> service.submit(data::add));
service.awaitTermination(1000, TimeUnit.MILLISECONDS);
// THEN
assertEquals(1000, data.getSum());
}
Orderbook methods should be synchronized
public void synchronized updateBids(double bidPrice, double bidVol) {
// Edit critical data here
}
Warning: When constructing an object that will be shared between threads, be very careful that a reference to the object does not "leak" prematurely. For example, suppose you want to maintain a List called instances containing every instance of class. You might be tempted to add the following line to your constructor: instances.add(this);
But then other threads can use instances to access the object before construction of the object is complete.
Your OrderBook getter getLasValue is leaking

Related

Java Runnable without static reference

I am trying to learn multi-threading using the runnable interface but I am having some trouble figuring out how to pass information. Basically, in the example below, I want to remove the static reference from the Hashmap but if I do that, the program breaks. How do I pass the hashmap to the runnable interface class without using the static keyword?
public class ThreadDemo {
static HashMap <String, Integer>map = new HashMap<>();
public String Hi() {
return "hi";
}
public String Hello() {
return "Hello";
}
public void addToMap(String item) {
if (map.containsKey(item)) {
map.put(item, map.get(item) + 1);
} else {
map.put(item, 1);
}
}
public static void main(String[] args) throws InterruptedException {
ArrayList<Thread> all = new ArrayList<>();
for (int i = 0; i < 50; ++i) {
threader threader = new threader();
all.add(new Thread(threader));
}
for (Thread thread : all) {
thread.start();
}
for (Thread thread : all) {
thread.join();
}
ThreadDemo td = new ThreadDemo();
System.out.println(td.map);
}
}
And a class that implements Runnable
public class threader implements Runnable {
ThreadDemo td = new ThreadDemo();
#Override
public void run() {
synchronized(td.map) {
td.addToMap(td.Hi());
td.addToMap(td.Hello());
}
}
}
A class instance is all about information.
public class threader implements Runnable {
final private ThreadDemo td;
public threader(ThreadDemo td) {
this.td = td;
}
#Override
public void run() {
..
}
}
then to use (details omitted, just the idea):
ThreadDemo theTd = new ThreadDemo();
for (...) {
threader threader = new threader(theTd);
all.add(new Thread(threader));
}
....
Of course, all threads are using the same ThreadDemo, with the same map, so you'll need to ensure access is interlocked in some way, e.g., by using synchronized. The ThreadDemo.addToMap method should be synchronized in this example, rather than the caller of addToMap. This puts the responsibility for the "care of the map" into the place that actually owns the map, and is consequently a better design.
I chose to share the ThreadDemo rather than just the map inside the ThreadDemo, since it looks to me that the intent of ThreadDemo is just to be a wrapper around the map.

Java FixedThreadPool with resources per thread?

This is a pseudocode version of my current working code:
public class DataTransformer {
private final boolean async = true;
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
public void modifyAsync(Data data) {
if (async) {
executorService.submit(new Runnable() {
#Override
public void run() {
modify(data);
}
});
} else {
modify(data);
}
}
// This should actually be a variable inside modify(byte[] data)
// But I reuse it to avoid reallocation
// This is no problem in this case
// Because whether or not async is true, only one thread is used
private final byte[] temp = new byte[1024];
private void modify(Data data) {
// Do work using temp
data.setReady(true); // Sets a volatile flag
}
}
Please read the comments. But now I want to use Executors.newFixedThreadPool(10) instead of Executors.newSingleThreadExecutor(). This is easily possible in my case by moving the field temp inside modify(Data data), such that each execution has it's own temp array. But that's not what I want to do because i want to reuse the array if possible. Instead I want for each of the 10 threads a temp array. What's the best way to achieve this?
As static variable is shared between all Threads, so you could declare as static. But if you want to use different values then either use Threadlocal or use different object.
With ThreadLocal you could do :
ThreadLocal<byte[]> value = ThreadLocal.withInitial(() -> new byte[1024]);
You could also use object like this:
public class Test {
public static void main(String[] args) {
try {
Test test = new Test();
test.test();
} catch (Exception e) {
e.printStackTrace();
}
}
class Control {
public volatile byte[] temp = "Hello World".getBytes();
}
final Control control = new Control();
class T1 implements Runnable {
#Override
public void run() {
String a = Arrays.toString(control.temp);
System.out.println(a);
}
}
class T2 implements Runnable {
#Override
public void run() {
String a = Arrays.toString(control.temp);
System.out.println(a);
}
}
private void test() {
T1 t1 = new T1();
T2 t2 = new T2();
new Thread(t1).start();
new Thread(t2).start();
}
}

Read and write into shared thread variables

first of all i am new to threads and shared variables. So please be kind with me ;-)
I'm having a class called Routing. This class recieves and handles messages. If a message is of type A the Routing-Object should pass it to the ASender Object which implements the Runnable Interface. If the message is of type B the Routing-Class should pass it to the BSender Object.
But the ASender and BSender Objects have common variables, that should be stored into the Routing-Object.
My idea now is to declare the variables as synchronized/volatile in the Routing-Object and the getter/setter also.
Is this the right way to synchronize the code? Or is something missing?
Edit: Added the basic code idea.
RoutingClass
public class Routing {
private synchronized Hashtable<Long, HashSet<String>> reverseLookup;
private ASender asender;
private BSender bsender;
public Routing() {
//Constructor work to be done here..
reverseLookup = new Hashtable<Long, HashSet<String>>();
}
public void notify(TopicEvent event) {
if (event.getMessage() instanceof AMessage) {
asender = new ASender(this, event.getMessage())
} else if (event.getMessage() instanceof BMessage) {
bsender = new BSender(this, event.getMessage())
}
}
public synchronized void setReverseLookup(long l, Hashset<String> set) {
reverseLookup.put(l, set);
}
public synchronized Hashtable<Long, Hashset<String>> getReverseLookup() {
return reverseLookup;
}
}
ASender Class
public class ASender implements Runnable {
private Routing routing;
private RoutingMessage routingMessage;
public ASender(Routing r, RoutingMessage rm) {
routing = r;
routingMessage = rm;
this.run();
}
public void run() {
handleMessage();
}
private void handleMessage() {
// do some stuff and extract data from the routing message object
routing.setReverseLookup(somethingToSet)
}
}
Some comments:
Hashtable is a thread-safe implementation, you do not need another "synchronized" keyword see this and this for more information
Avoid coupling, try to work with interfaces or pass the hashtable to your senders, see this for more information
Depending on the amount of senders, you might want to use a ConcurrentHashMap, it greatly improves the performance, see ConcurrentHashMap and Hashtable in Java and Java theory and practice: Concurrent collections classes
This would conclude something like...:
public interface IRoutingHandling {
void writeMessage(Long key, HashSet<String> value);
}
public class Routing implements IRoutingHandling {
private final Hashtable<Long, HashSet<String>> reverseLookup;
private ASender asender;
private BSender bsender;
public Routing() {
//Constructor work to be done here..
reverseLookup = new Hashtable<Long, HashSet<String>>();
}
public void notify(TopicEvent event) {
if (event.getMessage() instanceof AMessage) {
asender = new ASender(this, event.getMessage())
} else if (event.getMessage() instanceof BMessage) {
bsender = new BSender(this, event.getMessage())
}
}
#Override
public void writeMessage(Long key, HashSet<String> value) {
reverseLookup.put(key, value);
}
}
public class ASender implements Runnable {
private IRoutingHandling _routingHandling;
public ASender(IRoutingHandling r, RoutingMessage rm) {
_routingHandling = r;
routingMessage = rm;
this.run();
}
public void run() {
handleMessage();
}
private void handleMessage() {
// do some stuff and extract data from the routing message object
_routingHandling.writeMessage(somethingToSetAsKey, somethingToSetAsValue)
}
}

Threads calling both static and non-static method

Disclaimer: This code is copied from synchronized blocks for static and non-static methods
I made some modification to it. I want to know how to make threads call both synchronized static and non-static methods. I can make it work by wrapping the non-static method in a synchronized block. Is there any other way?
public class StaticNonStaticSynch
{
public static void main(String[] args)
{
final StaticNonStaticTest staticNonStaticTest = new StaticNonStaticTest();
Runnable runnable1 = new Runnable()
{
#Override
public void run()
{
staticNonStaticTest.nonStaticMethod();
}
};
Runnable runnable2 = new Runnable()
{
#Override
public void run()
{
StaticNonStaticTest.staticMethod();
}
};
Thread thread1 = new Thread(runnable1, "First Thread");
Thread thread2 = new Thread(runnable2, "Second Thread");
thread1.start();
thread2.start();
}
}
class StaticNonStaticTest
{
void nonStaticMethod()
{
//synchronized (StaticNonStaticTest.class){
for(int i=0;i<50;i++)
{
System.out.println("Non - Static method called by " + Thread.currentThread().getName() +" : = "+i);
}
// }
}
static synchronized void staticMethod()
{
for(int i=0;i<50;i++)
{
System.out.println("Static method called by " + Thread.currentThread().getName() +" : = "+i);
}
}
}
Remember that this:
public class MyClass {
public synchronized void doSomething() {
// Do something
}
public synchronized static void doSomethingStatic() {
// Do something static
}
}
Essentially compiles to this:
public class MyClass {
public void doSomething() {
synchronized(this) {
// Do something
}
}
public static void doSomethingStatic() {
synchronized(MyClass.class) {
// Do something static
}
}
}
Notice that they don't synchronize on the same thing. To fix this, create an object for both of them to lock on (known as a mutually exclusive object, or a "mutex"):
public class MyClass {
private static final Object MUTEX = new Object();
public void doSomething() {
synchronized(MUTEX) {
// Do something
}
}
public static void doSomethingStatic() {
synchronized(MUTEX) {
// Do something static
}
}
}
That should make it so that only one of these two methods are running at the same time across multiple threads.
A couple tips:
Always use synchronized(variable) on a variable that's final.
The MUTEX doesn't have to be strictly a mutex, it could be an actual object. See the example below.
Remember how the synchronized modifier on methods is effectively implemented. It's just like a synchronized block on this or MyClass.class.
Besides having an object that's strictly a mutex, you can use any field that's final. For example, to synchronize on a Map during iteration:
public class MyClass {
private static final Map<String, String> map = new HashMap<String, String>(); // Java 6
private static final Map<String, String> map = new HashMap<>(); // Java 7
public static void put(String k, String v) {
synchronized(map) {
map.put(k, v);
}
}
public static void printAll() {
synchronized(map) {
for (Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
}
This code guarantees that you'll never get a ConcurrentModificationException
You can have both methods internally synchronize on a common lock object. Otherwise, the only way to have the instance method block while the static method executes is to synchronize on the class object (as you have in the commented lines).
Synchronized instance methods synchronize on the object instance; synchronized static methods synchronize on the class instance. Note that synchronized static methods might execute simultaneously if there are two instances of the class (say, from different class loaders). You usually would know if this is happening, because you have to do considerable work to make it happen.
Here's one way to synchronize both static and instance methods on a common lock object:
class StaticNonStaticTest {
private static final Object LOCK_OBJECT = new Object();
void nonStaticMethod() {
synchronized (LOCK_OBJECT) {
for (int i=0; i<50; i++) {
System.out.println("Non - Static method called by "
+ Thread.currentThread().getName() + " : = " + i);
}
}
}
static void staticMethod() {
synchronized (LOCK_OBJECT) {
for (int i=0; i<50; i++) {
System.out.println("Static method called by "
+ Thread.currentThread().getName() +" : = "+i);
}
}
}
}

I want the main method to print out the value x, which is returned by running threads

I want the main method to print out the value x, which is returned by running threads. How can I do it? Hope that my question makes sense.
import java.*;
public class ServerStudentThread extends Thread
{
public ServerStudentThread(Socket x) {
client = x;
}
public void run()
{
//Do something here and return an integer,
// for example **x**
}
public static void main(String args[]) throws Exception {
// ...
// I want to print out x value here.
// But as you can see, x disappears after thread finish its job.
}
}
You would have to make x a field in the ServerStudentThread class, not a local variable. then add a method in the class like getValue() that returns x. From the main method, after you create the thread, run it, call the getValue() mehod on the class to print get the value of x and print it.
If you are using java 5 there is an Callable Interface.kindly look at this link
http://java-x.blogspot.com/2006/11/java-5-concurrency-callable-and-future.html
// Code pasted from the link
public class CallableTester {
public static void main(String[] args) {
Callable<Integer> callable = new CallableImpl(2);
ExecutorService executor = new ScheduledThreadPoolExecutor(5);
Future<Integer> future = executor.submit(callable);
try {
System.out.println("Future value: " + future.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class CallableImpl implements Callable<Integer> {
private int myName;
CallableImpl(int i){
myName = i;
}
public Integer call() {
for(int i = 0; i < 10; i++) {
System.out.println("Thread : " + getMyName() + " I is : " + i);
}
return new Integer(getMyName());
}
public int getMyName() {
return myName;
}
public void setMyName(int myName) {
this.myName = myName;
}
}
You should create thread (call Thread t = new ServerStudentThread(), then call t.start() then you should wait until the tread is done. For example call t.join().

Categories

Resources