I am trying to understand the thread safety mechanism in java and I need some help. I have a class:
public class ThreadSafe {
private Executor executor = new ScheduledThreadPoolExecutor(5);
private long value = 0;
public void method() {
synchronized (this) {
System.out.println(Thread.currentThread());
this.value++;
}
}
private synchronized long getValue() {
return this.value;
}
public static void main(String... args) {
ThreadSafe threadSafe = new ThreadSafe();
for (int i = 0; i < 10; i++) {
threadSafe.executor.execute(new MyThread());
}
}
private static class MyThread extends Thread {
private ThreadSafe threadSafe = new ThreadSafe();
private AtomicBoolean shutdownInitialized = new AtomicBoolean(false);
#Override
public void run() {
while (!shutdownInitialized.get()) {
threadSafe.method();
System.out.println(threadSafe.getValue());
}
}
}
}
Here I am trying to make the value thread safe, to be accessed only by one thread at a time. When I am running this program I see that there is more than one thread operating on the value even if I wrap it within the synchronized block. Of course this loop will be infinite but its just an example, I am stopping this program manually after few seconds, so I have:
2470
Thread[pool-1-thread-3,5,main]
2470
Thread[pool-1-thread-5,5,main]
2470
Thread[pool-1-thread-2,5,main]
Different threads are accessing and changing this value. Can somebody explain to me why is this so? And how to make this global variable thread safe?
Each thread has its own ThreadSafe, and each ThreadSafe has its own, different value. Moreover, synchronized methods lock on this, so each ThreadSafe is locking on itself -- and none of them are being shared among threads. This is called thread-locality, and it's the easiest way to ensure thread safety. :)
To get at the experiment that I think you want, you'd need to change MyThread such that its constructor takes a ThreadSafe argument (instead of constructing one). Then, have the main method create one ThreadSafe and give it to each MyThread at construction time.
You are getting the same value every time because each of your Runnables has its own instance of the ThreadSafe class.
If you want them all to share the same class, then you are going to need to only have one instance of ThreadSafe and pass it into all of your jobs -- see below. As mentioned, an AtomicLong is the way to go if you want a thread-safe shared long.
Also, your MyThread class should not extend Thread. It should instead implements Runnable. Your code is working because Thread already implements Runnable. If you did myThread.interrupt() it would not actually be interrupting the thread because it is the thread-pool threads that are calling your run() method.
Something like the following would work:
ThreadSafe threadSafe = new ThreadSafe();
for (int i = 0; i < 10; i++) {
threadSafe.executor.execute(new MyRunnable(threadSafe));
}
...
private static class MyRunnable implements Runnable {
private final ThreadSafe threadSafe;
public MyRunnable(ThreadSafe threadSafe) {
this.threadSafe = threadSafe;
}
...
Related
I've wrote some multithreading code in java and synchronized method that changed variable, but it doesn't synchronized my code, I still get random values. There is my code:
public class Main {
public static void main(String[] args) throws Exception {
Resource.i = 5;
MyThread myThread = new MyThread();
myThread.setName("one");
MyThread myThread2 = new MyThread();
myThread.start();
myThread2.start();
myThread.join();
myThread2.join();
System.out.println(Resource.i);
}
}
class MyThread extends Thread {
#Override
public void run() {
synMethod();
}
private synchronized void synMethod() {
int i = Resource.i;
if(Thread.currentThread().getName().equals("one")) {
Thread.yield();
}
i++;
Resource.i = i;
}
}
class Resource {
static int i;
}
Sometimes I get 7, sometimes 6, but I've synchronized synMethod, as I understand no thread should go at this method while some other thread executing this, so operations should be atomic, but they are not, and I can't understand why? Could you please explain it to me, and answer - how can I fix it?
Adding the synchronized method is like synchronizing on this. Since you have two different instances of threads, they don't lock each other out, and this synchronization doesn't really do anything.
In order for synchronization to take effect, you should synchronize on some shared resource. In your example, Resource.class could by a good choice:
private void synMethod() { // Not defined as synchronized
// Synchronization done here:
synchronized (Resource.class) {
int i = Resource.i;
if (Thread.currentThread().getName().equals("one")) {
Thread.yield();
}
i++;
Resource.i = i;
}
}
Let's have a look at definition of synchronized methods from oracle documentation page.
Making the 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.
Coming back to your query:
synMethod() is a synchronized method object level. Two threads accessing same synchronized method acquire the object lock in sequential manner. But two threads accessing synchronized method of different instances (objects) run asynchronously in the absence of shared lock.
myThread and myThread2 are two different objects => The intrinsic locks are acquired in two different objects and hence you can access these methods asynchronously.
One solution : As quoted by Mureinik, use shared object for locking.
Other solution(s): Use better concurrency constructs like ReentrantLock etc.
You find few more alternatives in related SE question:
Avoid synchronized(this) in Java?
I am pretty new to using multithreading, but I want to invoke a method asynchronously (in a separate Thread) rather than invoking it synchronously. The basic idea is that I'm creating a socket server with an object in memory, so for each client I will have to run something like object.getStuff() asynchronously.
The two constructs I found were:
having the class implement Runnable and threading this and
declaring a runnable class within a method.
Additionally this method needs a return value- will it be necessary to use Executor and Callable to achieve this? Could someone point me in the right direction for implementing this?
I have tried implement option 2, but this doesn't appear to be processing concurrently:
public class Test {
private ExecutorService exec = Executors.newFixedThreadPool(10);
public Thing getStuff(){
class Getter implements Callable<Thing>{
public Thing call(){
//do collection stuff
return Thing;
}
}
Callable<Thing> callable = new Getter();
Future<Thing> future = exec.submit(callable);
return future.get();
}
}
I am instantiating a single test object for the server and calling getStuff() for each client connection.
Threading Tutorial
The Java tutorial on concurrency has a good section on this. It's at https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html. Essentially, you can either implement Runnable or Callable, or inherit from Thread.
Subclassing Thread
You can write a class, including an anonymous inner class, that extends Thread. Instantiate it, then invoke the start() method.
public class MyThread extends Thread {
public void run() {
System.out.println("This is a thread");
}
public static void main(String[] args) {
MyThread m = new MyThread();
m.start();
}
}
Implementing Runnable
You can write a class that implements Runnable, then wrap an instance in a Thread and invoke start(). Very much like the previous.
public class MyRunnable implements Runnable {
public void run() {
System.out.println("This is a thread");
}
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
(new Thread(r)).start();
}
}
Return Value
Runnable doesn't allow for return values. If you need that, you need to implement Callable instead. Callable looks a lot like Runnable, except you override the call() method instead of the run() method, and you need to give it to an ExecutorService.
public class MyCallable implements Callable<Integer> {
public Integer call() {
System.out.println("A thread using Callable<Integer>");
return 42;
}
public static void main(String[] args) {
MyCallable c = new MyCallable();
Future<Integer> f = Executors.newSingleThreadExecutor().submit(c));
System.out.println("The thread returned: " +
f.get());
}
}
The two constructs I found were 1) having the class implement Runnable and threading 'this' and 2) declaring a runnable class within a method.
Option (2) probably is better. Most programs would be improved if they had more classes, not fewer. Each named entity in a program—each package, class, method, whatever—should have just one responsibility. In your option (1), you are asking the class to do two things.
For your option (2), you don't actually have to declare a whole class. You can either use an anonymous inner class, or if you can go with Java8 all the way, you can use a lambda expression. Google for either one to learn more.
Additionally this method needs a return value.
The classic way, is for the Runnable object to return the value through one of its own fields before the thread terminates. Then the parent thread, can examine the object and get the return value afterward.
Will it be necessary to use Executor and Callable to achieve this?
Necessary? A lot of people think that ExecutorService is a Good Thing.
Sounds like you are creating a server that serves multiple clients. Do these clients continually connect and disconnect? The advantage of using a thread pool (i.e., ThreadPoolExecutor) is that it saves your program from continually creating and destroying threads (e.g., every time a client connects/disconnects). Creating and destroying threads is expensive. If you have a lot of clients connecting and disconnecting, then using a thread pool could make a big difference in the performance of your server.
Creating and managing threads by yourself is generally bad approach.
As you already pointed - use Executors utility class to create executor and submit Callables to it.
public class RunWResult implements Runable{
private volatile ResultType var;
//the thread method
public void run(){
...
//generate a result and save it to var
var = someResult();
//notify waiting threads that a result has been generated
synchronized(this){
notify();
}
}
public ResultType runWithResult(){
//run the thread generating a result
Thread t = new Thread(this);
t.start();
//wait for t to create a result
try{
wait();
}catch(InterruptedException e){}
//return the result
return var;
}
}
Is it bad programming to initialize two threads with the same instance of a runnable? What difference would it make to initialize with separate instances of a runnable, and does sharing memory locations at all for the same instance of a runnable have anything to do with performance?
public static void main(String[] args)throws Exception {
H h = new H();
H h2 = new H();
Thread j = new Thread(h);
j.setName("11");
Thread jj = new Thread(h);//instead of new H()
jj.setName("22");
j.start();
jj.start();
}
class H implements Runnable {
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName());
}
}
}
It's absolutely fine to do it so long as the code you're running is designed to support that. Not only will it save some memory by having a single instance instead of multiple instances, but if those threads are trying to communicate via shared data, then it may be absolutely required!
Admittedly communicating via shared state is where threading often gets tricky, so this needs to be done carefully, but from the point of view of the threading system itself, there's absolutely no problem in having two threads call the run method of a single Runnable instance.
Since H doesn't have any instance state, using multiple instances won't matter. You need to take care when the Runnable instances start storing state.
public class Main implements Runnable {
volatile int i;
public void run() {
for (i = 0; i < 100; i++) {
System.out.println(i);
}
}
public static void main(String[] args) {
Main a = new Main();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start();
t2.start();
}
}
What gets printed? When you do need to share state between threads, it's a good idea to use the classes in java.util.concurrent. They were written primarily by an expert in multithreading (Doug Lea, author of Concurrent Programming in Java) and tested by many people. Save yourself some heartache. :)
Is it bad programming to initialize two threads with the same instance of a runnable?
Not specifically. However, if the Runnable instance has instance fields, then you'll need to make sure that all access to the fields by the thread is properly synchronized, and this will make the code more complicated.
What difference would it make to initialize with separate instances of a runnable, and does sharing memory locations at all for the same instance of a runnable have anything to do with performance?
The memory saved by sharing a Runnable instance between multiple threads is insignificant ... unless the Runnable holds a significant amount of instance data. (And if it does, the chances are that this will make the instance non-shareable.)
Your H class is an example where sharing instances is safe, but pointless since the memory saving is insignificant. (A Runnable object with no instance fields occupies roughly 8 to 16 bytes, depending on the platform.)
To make understand easily(based on the comment of Stephen), added the below program block about the impact of accessing the instance variable from a non-synchronized block with the same instance of Runnable displays the unexpected results.
public class SynchronizedInstanceMethod implements Runnable{
private int counter;
public SynchronizedInstanceMethod(int counterValue){
this.counter = counterValue;
}
private synchronized void displayMessage(){
System.out.println(" Display Message ");
}
private void modifyCounter(){
this.counter++;
System.out.println("Value -- "+ this.counter);
}
#Override
public void run() {
this.displayMessage();
this.modifyCounter();
}
public static void main(String[] args) {
SynchronizedInstanceMethod instance = new SynchronizedInstanceMethod(5);
new Thread(instance).start();
new Thread(instance).start();
}
}
I have the following codes. I expected one thread to execute its synchronized method completely and then allow another one to access the same method. However, this is not the case.
public class Threads {
/**
* #param args
*/
public static void main(String[] args) {
//Thread Th = new Threads();
Thread th = new Thread (new thread1 ());
th.start();
Thread th1 = new Thread (new thread1 ());
th1.start();
}
}
class thread1 implements Runnable{
String name = "vimal";
public void run() {
System.out.println("Runnable "+this.name);
setNAme("Manish");
}
public synchronized void setNAme(String name){
try {
System.out.println("Thread "+Thread.currentThread().getName());
wait(1000);
this.name = name;
System.out.println("Name "+this.name);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have one output as
Runnable vimal
Thread Thread-0
Runnable vimal
Thread Thread-1
Name Manish
Name Manish
What is the use of synchronized here and how do I make my method to run completely before another accesses it?
synchronized has no effect here because you are not synchronizing on the same object in both cases. When applied to an instance method, the synchronized keyword causes the method to be synchronized on this. So in each case you are synchronizing on the instance of thread1, and there are two of those.
The more interesting test would be when you run the same instance of thread1 in two threads simultaneously. In that case, calling wait(1000) is a very bad thing to do because (as documented) it releases the lock on this. You want to use Thread.sleep(1000) instead in your code.
If you need to have two instances of thread1, you need to synchronize on some shared object, possibly like this:
private static final Object lockObject = new Object();
public void setName(String newName) {
synchronized(lockObject) {
doSetName(newName);
}
}
You will have to remove the call to wait(1000). It looks like what you actually want is a call to Thread.sleep(1000), if you simply want to pause the current thread, this does not release ownership of any monitors.
From the javadoc for Object.wait().
This method causes the current thread (call it T) to place itself in
the wait set for this object and then to relinquish any and all
synchronization claims on this object. Thread T becomes disabled for
thread scheduling purposes and lies dormant until one of four things
happens:
Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be
awakened.
Some other thread invokes the notifyAll method for this object.
Some other thread interrupts thread T.
The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into
consideration and the thread simply waits until notified.
The thread T is then removed from the wait set for this object and
re-enabled for thread scheduling. It then competes in the usual manner
with other threads for the right to synchronize on the object; once it
has gained control of the object, all its synchronization claims on
the object are restored to the status quo ante - that is, to the
situation as of the time that the wait method was invoked. Thread T
then returns from the invocation of the wait method. Thus, on return
from the wait method, the synchronization state of the object and of
thread T is exactly as it was when the wait method was invoked.
UPDATE: As has been mentioned in other answers, you are not synchronizing on the same object. Once you do, you will still suffer the same output, due to the issue I have mentioned. You will need to fix both for your desired results.
The output is correct, you are creating to independent threads that do not share any data. Thus both threads start with first string, and after some time, the string is changed and printed.
You're creating 2 thread1 objects. They each have their own setNAme method. Synchronized methods only synchronize on the object, not the class. Unless the method is static.
You have two Threads here with independent name variables and independent monitors, so each Thread is only accessing its own members. If you want to have the threads interact with each other you'll have to implement such an interaction.
you are creating two separate thread1 objects and running them. Each thread has it's own copy of the name variable as well as the setName function. Make them both static and you will see the effects of synchronization.
You are locking on two different instance of the objects where you dont need any synchronization at all. You need to synchronize only if you are working on a shared data. I think you meant to write a test like the below.
If you test this, you will realize that the second thread will wait until the first thread is completed with the synchronized method. Then take out the synchronized word and you will see both threads are executing at the same time.
public class SynchronizeTest {
public static void main(String[] args) {
Data data = new Data();
Thread task1 = new Thread(new UpdateTask(data));
task1.start();
Thread task2 = new Thread(new UpdateTask(data));
task2.start();
}
}
class UpdateTask implements Runnable {
private Data data;
public UpdateTask(Data data) {
this.data = data;
}
public void run() {
try {
data.updateData();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Data {
public synchronized void updateData() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(5000);
System.out.println(i);
}
}
}
How can I prevent from concurrent access. I have code like this
public class MC implements Runnable {
public void run() {
sync();
}
public static void main(String p[]){
MC mc = new MC();
MC mc2 = new MC();
MC mc3 = new MC();
MC mc4 = new MC();
Thread t = new Thread(mc);
t.start();
Thread t2 = new Thread(mc2);
t2.start();
Thread t3 = new Thread(mc3);
t3.start();
Thread t4 = new Thread(mc4);
t4.start();
}
private synchronized void sync(){
try {
System.out.println(System.currentTimeMillis());
Thread.sleep(10000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
and I am getting output like this
1307082622317
1307082622317
1307082622317
1307082622317
BUILD SUCCESSFUL (total time: 11 seconds)
any advice?
make your method static:
private static synchronized void sync();
your method as coded is synchronized on the instance, but each thread has its own instance, so there's no synchronization.
static methods are synchronized on the Class object, of which there is only one per class, so all instances will synchronize on static methods.
You've got four separate MC objects. Typically running an instance method on those (sync), they shouldn't interfere with each other. You can use a synchronized block to make sure only one runs at a time, but you need to consider what to synchronize on:
If you synchronize on a separate object per instance, that would stop two threads from running the code for the same object. That's effectively what you've got now, but you're implicitly synchronizing on this, which I would discourage you from doing. (Any other code could synchronize on the same object.)
If you synchronize on an object that all the instances know about (e.g. via a static variable) then that would only let one thread run the code at all.
It sounds like you want the latter approach, but it doesn't sound like great design to me. If you really want to implement it that way, you'd use:
public class MC implements Runnable {
private static readonly Object lock = new Object();
...
private void sync() {
synchronized (lock) {
try {
System.out.println(System.currentTimeMillis());
Thread.sleep(10000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
Keeping sync as a synchronized method but making it static would also work, but again you'd be locking on a publicly visible object (MC.class) which I generally discourage.
For the desired functionality, you can make the sync function static. I don't talk about the goodness of design. It just do it the way you like!
private static synchronized void sync()
You are instantiating four objects, and sychronized is on different monitor. Either make sync static so that the actual class will be the monitor, or when you instantiate, pass same monitor object to all four, then sync on it
use a static lock tisynchronize your method. lock classes are inside the java.concurent package
Hi u are creating new instances of ur class MC, synchronized method guarantees single access for one instance if it is not static method.
I would suggest u have a private static variable say Integer lock, and then synchronize on it:
private void sync()
{
synchronized (lock)
{
try {
System.out.println(System.currentTimeMillis());
Thread.sleep(10000);
} catch (InterruptedException ex){
ex.printStackTrace();
}
}
}