I use 2-dimensional array in Java. But now, I want to use this class for multi-thread. How can I do that?
I know that how can I do a thread safe function (add synchronized keyword). What happens if clear and getItem functions are triggered at the same time? How can I do thread safe inctance for this case?
public class ThreadSafeArray {
int ROW_MAX_COUNT = 1024;
int rowCount = 0;
int counterForRow = 0;
private Object [][] objInstances = new Object[ROW_MAX_COUNT][];
public synchronized void addItem(Object obj) {
if(counterForRow == ROW_MAX_COUNT) {
objInstances[++rowCount] = new Object[ROW_MAX_COUNT];
counterForRow = 0;
}
objInstances[rowCount][counterForRow++] = obj;
}
public synchronized void clear() {
objInstances = new Object[ROW_MAX_COUNT][];
rowCount = 0;
counterForRow = 0;
}
public synchronized Object getItem(int index) {
int row = index / ROW_MAX_COUNT;
int column = index % ROW_MAX_COUNT;
if((row <= rowCount) && (column <= counterForRow)) {
return objInstances[row][column];
}
return null;
}
}
IN your code, clearand getItem are instance methods. Putting synchronized on an instance method means that the thread has to acquire the lock (the "intrinsic lock") on the object instance that the method is called on before the thread can start executing any code in that method.
Making instance methods synchronized has two effects(from java guide):
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
So,your class is already thread-safe for these two methods.
What happens if clear and getItem functions are triggered at the same time?
One will wait until another is finished.
How can I do thread safe inctance for this case?
It is already thread-safe.
Related
I was reading about semaphore's and in the code example it confused me why a semaphore was used when the code uses sychronization around the method that is ultimately called. Isn't that doing the same thing, i.e. restricting 1 thread at a time to perform the mutation?
class Pool {
private static final int MAX_AVAILABLE = 100;
private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
public Object getItem() throws InterruptedException {
available.acquire();
return getNextAvailableItem();
}
public void putItem(Object x) {
if (markAsUnused(x))
available.release();
}
// Not a particularly efficient data structure; just for demo
protected Object[] items = ... whatever kinds of items being managed
protected boolean[] used = new boolean[MAX_AVAILABLE];
protected synchronized Object getNextAvailableItem() {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (!used[i]) {
used[i] = true;
return items[i];
}
}
return null; // not reached
}
protected synchronized boolean markAsUnused(Object item) {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (item == items[i]) {
if (used[i]) {
used[i] = false;
return true;
} else
return false;
}
}
return false;
}
}
I'm referring to the call to getItem() which calls acquire(), and then calls getNextAvailableItem, but that is synchronized anyhow.
What am I missing?
Reference: http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Semaphore.html
The semaphore and the synchronized block are doing two different jobs.
The synchronized keyword is protecting getNextAvailableItem() when it is accessing and mutating the array of items. An operation that would corrupt if it was not restricted to one thread at a time.
The semaphore will allow up to 100 threads through, significantly more than 1. Its purpose in this code sample is to block requests for an object from the pool when the pool is empty, and to then unblock one thread when an object is returned to the pool. Without the semaphore, things would look like they were working until the pool was empty. At that time requesting threads would not block and wait for an object to be returned, but would instead receive null.
A Semaphore gives you a thread-safe counter that blocks when the acquire has been called beyond the initial limit. release can be used to undo an acquire.
It will guarantee that if a call to acquire succeeds there is sufficient capacity to hold the new item.
In the sample there are loops that look for a free item. Using a Semaphore ensures that none of those loops are begun until there is a free item.
synchronized only guarantees that ony one thread can execute this section of code at a time.
I've a question about synchronization in java. In the following Java program I dont get any output. But, if I remove the synchronized statement from the method IFoo.s() I'll get some output. It seems like the methods IFoo.setP() and IFoo.s() are synchronized among each other. But 'synchronized' should only prevent that two threads call the synchronized method at the same time, right?
package com.example.relectiontest;
import java.awt.Point;
import java.util.Random;
public class Main {
public static void main(String[] args) throws Exception{
final IFoo f = new IFoo();
Runnable r = new Runnable() {
public void run() {
Random r = new Random();
int a = r.nextInt(5)+1;
for(int i=0;i<1000000;++i){
f.setP(a);
}
}
};
Runnable r2 = new Runnable() {
public void run() {
for(int i=0;i<1000000;++i){
f.s();
}
}
};
Thread T1 = new Thread(r, "T1");
Thread T2 = new Thread(r, "T2");
Thread T3 = new Thread(r2, "T3");
T3.start();
T1.start();
T2.start();
}
private static class IFoo{
private Point p = new Point();
public synchronized void setP(int a){
//System.out.println("p1 "+Thread.currentThread());
p.x = a;
p.y = p.x;
int x = p.x , y = p.y;
if(x != y)
System.out.println(Thread.currentThread()+"\t"+x+" "+y);
//System.out.println("p2 "+Thread.currentThread());
}
public synchronized void s(){
//System.out.println("s");
p.x = 0;
}
}
}
So, why I cant see any output?
regards
Because thanks to synchronization x != y will never be true.
In your unsynchronized version s() has the chance of setting p.x to 0 every once in a while (even though it's not synchronized properly).
In the synchronized version s() must wait until setP is finished (since they're both synchronized, sharing the implicit this lock), and thanks to the logic in setP the condition can not be true.
Your example is overly complex. You can write it out as follows (adding synchronized on both methods to see that nothing will be printed):
private static class IFoo {
volatile int x = 0;
public void setP(int a) {
x = a;
if(x != a)
System.out.println("Someone changed x!");
}
public void s() {
x = 0;
}
}
Also note that static synchronized methods synchronize on the Class object since they have no this. Instance and static methods therefore won't lock each other unless you explicitly synchronize on a common lock.
In Java all synchronized calls are synchronized on an object. For instance methods, they object is the class instance - so in your case setP and s are both synchronized on the instance of IFoo.
This allows you to control access to shared fields which are accessed through more than one method. With your code, this will be exactly what you need - you need to make sure you don't have one thread in setP changing the state while another in s is reading it.
If you prefer finer control you can use synchronized blocks, which allow you to specify the object to lock on:
private final Object o=new Object();
public void method(){
synchronized (o){
//Synchronized code
}
}
This is the generally generally recommended approach - it allows you to encapsulate your lock, so you don't risk some other class interfering with your locks and potentially DOSing your code.
Static methods are synchronized on the class object (such as IFoo.class).
From documentation:
making these methods synchronized has two effects:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing
a synchronized method for an object, all other threads that invoke
synchronized methods for the same object block (suspend execution)
until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent
invocation of a synchronized method for the same object. This
guarantees that changes to the state of the object are visible to all
threads.
The output will be displayed only when:
if(x != y)
Because in lines:
p.x = a;
p.y = p.x;
int x = p.x , y = p.y;
You make x == y that output is not displayed.
When you remove synchronization keyword from s method - the threads sometimes set x to 0 and this make if(x != y) - to true. and output is visible.
Because normally you shouldn't get any output as x should be equal to y.
However, when you remove the synchronized keyword, two threads execute at the same time and you may get an output if s() executes between p.y=p.x and x=p.x statements.
class Call {
int count;
public void increment() {
for (int i = 0; i < 1000; i++)
count++;
}
}
class Caller implements Runnable {
Call c;
public Caller(Call c) {
this.c = c;
}
#Override
public void run() {
// TODO Auto-generated method stub
c.increment();
}
}
class Calling implements Runnable {
Call c;
public Calling(Call c) {
this.c = c;
}
#Override
public void run() {
// TODO Auto-generated method stub
synchronized (c) {
c.increment();
}
}
}
public class SynchronizedBlock {
public static void main(String[] args) throws InterruptedException {
Call call = new Call();
Calling calling = new Calling(call);
Caller caller = new Caller(call);
Thread t1 = new Thread(caller);
Thread t2 = new Thread(calling);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("caller:" + caller.c.count);
}
}
Here have made increment method synchronized in 1 class and in other class i havent made it as synchronized. When i run the above code , it sometimes gives value of count less than 2000 .
As per my understanding, Since Calling class's object has already locked the object, so there is no need to synchronize in Caller class increment method.
Could you please help me in understanding the logic here.
Since Calling class's object has already locked the object, so there
is no need to synchronize in Caller class increment method.
Your understanding is incorrect. In order for parallel actions on a variable to be deterministic, you must have some sort of synchronization in place on every access/modification to that variable**.
You need to synchronize in Caller as well.
**: This is a necessary but insufficient condition to guarantee determinism.
synchronized keyword in java means that lock will be acquired before entering the block and released after exit.
Since t2 acquires/releases the lock and t1 doesn't, there is effectively no synchronization going on. t1 just goes in the block whenever the CPU time is assigned to it.
t2 also always goes in the block without waiting because the lock is never acquired by t1.
--
If you synchronize the increment method your program will work correctly:
class Call {
int count;
public synchronized void increment() {
for (int i = 0; i < 1000; i++)
count++;
}
}
After this change you can remove the synchronized block from t2.
What's probably happening when you get the correct value of 2000, happens between the lines:
t1.start();
t2.start();
This is because the execution of public void increment(); is finishing in a single quantum, before the t2.start() line is even executed. A Thread Quantum is the time that the thread runs before a different thread can run on the processors core.
The first thread doesn't lock the object, and occasionally a single quantum will not encompass the entire execution of increment(), which leaves time for thread 2 to begin executing and working on the same object data. This will result in 2 copies of the variable count existing at the same time, competing for the same memory.
Try increasing the amount of increments for (int i = 0; i < 1000; i++) to some number like for (int i = 0; i < 10000000; i++). You will most likely see the application begin to fail more often.
I saw this on Java's synchronization tutorial:
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
The tutorial says that subsequent calls by different threads block, like so:
A: increment();
B: increment(); <-- has to wait for A to finish
...but say two threads interleave like so:
A: increment(): load c -> 0;
B: decrement(): load c -> 0;
A: increment(): increment c -> 1;
B: decrement(): decrement c -> -1;
A: increment(): save c -> 1;
B: decrement(): save c -> -1;
Finally: c == -1;
Neither has to wait, in my understanding of the tutorial; so is c protected from memory inconsistency?
Due to popular demand: the tutorial
The synchronized keyword on a (non-static) method causes the method to lock on the enclosed object - in this case the instance of SynchronizedCounter. Thus each synchronized method prevents each other synchronized method from running in another thread. So in your example, thread A's call to increment() would complete before thread B's call to decrement() would start. Therefore your class is thread safe.
Your current understanding of Java threading is not complete. In Java, every object has an "implicit lock", which is the object itself. And the "synchronized" keywords uses this implicit lock to make your code thread safe. The following code has the same effect:
public class SynchronizedCounter {
private int c = 0;
public void increment() {
synchronized(this){
c++;
}
}
public void decrement() {
synchronized(this){
c--;
}
}
public int value() {
synchronized(this){
return c;
}
}
}
Also, if you want to, you can declare multiple objects to server as simple lock objects. This, again, has the same effect:
public class SynchronizedCounter {
private int c = 0;
private Object lockObject;
public void increment() {
synchronized(lockObject){
c++;
}
}
public void decrement() {
synchronized(lockObject){
c--;
}
}
public int value() {
synchronized(lockObject){
return c;
}
}
}
Before synchronized method or synchronized block (also sometimes called guarded block) is executed, the executing thread must first obtain the lock. When it doesn't, the code in synchronized methods/block won't be executed. That's why your example will always work, because all the methods share one lock (the implicit one), none of the methods can be executed simultaneously with other methods.
For advanced locking mechanisms, please see the Lock interface.
Yes, c is protected from memory inconsistency.
However if the value of c is copied out of the object via the getter method, then that copy will live separately and become out of date.
None of the methods on SynchronizedCounter can be invoked simultaneously because they are all declared synchronised.
This does two things, firstly it creates a mutually exclusive region by requiring any thread to enter a monitor (http://en.wikipedia.org/wiki/Monitor_%28synchronization%29) and secondly it places memory barriers (http://en.wikipedia.org/wiki/Barrier_%28computer_science%29) at the entry to the method and the exit.
Thus only one thread can modify c at a time, and no matter which thread on which CPU core is executing that method then it will read the latest value of c and will make its change to c visible to the next thread that enters the monitor. For more on the memory barrier side, Doug Lea wrote a very useful guide at http://gee.cs.oswego.edu/dl/jmm/cookbook.html.
I am very puzzled by the behavior of MySQL and java threading. I declare this as synchronized and the results I get are clashing. That means that more than one thread is accessing the same function at the same time. This code segment is in the runnable class.
MachineID is the thread id in the order with which it was invoked in the for loop. (It is jsut a number from 1 to 100).
I don't think the table is required information to
This is the output I get
144 18
144 17
144 11
144 13
144 10
144 9
public synchronized int getRow() throws SQLException{
String query="SELECT * FROM Searches WHERE checked='0'";
ResultSet results = this.database.executeQuery(query);
int id=0;
if(results.next()){
id=results.getInt(1);
System.out.println(id+" "+this.machineID);
query = "UPDATE Searches SET checked='1' WHERE ID_num='"+id+"'";
System.out.println(this.database.executeUpdate(query));
}
return id;
}
public void run() {
int id=getRow();
if (id!=0) {
}
}
this is where I invoke my threads
for (int i = 0; i < verifier.length; i++) {
verifier[i]=new Thread(new Verifier(main.database,i+1));
verifier[i].start();
}
Assuming the getRow() method belongs to the Verifier class, then there is no blocking going on. When you declare synchronized on a method, it is equivalent to synchronizing on the instance itself. However, you are spawning a new Verifier instance for each Thread. Each of those is synchronizing on themselves so none block any of the others.
Consider sharing a Lock object with each instance of Verifier or synchronizing on a shared object.
Object lock = new Object();
for (int i = 0; i < verifier.length; i++) {
verifier[i]=new Thread(new Verifier(main.database,i+1, lock));
verifier[i].start();
}
...
public int getRow() throws SQLException{
synchronized(lock) {
...
}
}
Sotirios has hit the nail on the head. But instead of having a new variable to lock on, I would use just a single Verifier, and call it from multiple threads. So you'll have
Verifier oneVerifier = new Verifier(main.database, 1);
for (int i = 0; i < verifier.length; i++) {
verifier[i]=new Thread(oneVerifier);
verifier[i].start();
}
Note - I don't know what that second argument to the Verifier constructor is supposed to be. Chances are, you don't actually need it, but since you don't actually show the constructor, I thought I'd leave it in.
No synchronization is happening at all it's is similar to
synchronize(this)
And the same instance is not shared across the threads so there is no synchronization happening at all.
So you need to share a lock object across the Runnable instances i.e. Verifier in constructer like:
public class Verifier implements Runnable{
private final Object lock;
public Verifier(Object lock){
this.lock=lock;
}
Than you can synchronize on the lock like:
synchronize(lock)
else you can synchronize on the class object as well:
synchronize(Verifier.class)