I was wondering if it was okay that you give a thread access to an instance of a class
so you can perform operations on certain members/variables of that class.
For example, I have both a main thread and a thread.
I'm giving the second thread access to the instance of the main class
so I can perform an operation on x.
However, what if at some point in the future I decide to do operations on x
in the main thread? Or just simply reading from x. What if both the other thread and the main
thread want to read x at the same time?
Is this at all okay by the way I have it structured in my code to do?
package test;
import java.lang.Thread;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class AThread extends Thread {
Test test;
AThread(Test test) {
this.test = test;
}
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
public void run() {
String msg;
while ((msg = queue.poll()) != null) {
// Process the message
//System.out.println(msg); //should print "hello"
if (msg.equals("up")) {
test.setX(test.getX()+1);
System.out.println(test.getX());
}
}
}
}
public class Test {
AThread aThread;
private int x = 5;
void setX(int x){
this.x = x;
}
int getX(){
return x;
}
Test() throws InterruptedException{
System.out.println("MainThread");
aThread = new AThread(this);
aThread.start();
while (true) {
aThread.queue.put("up");
}
}
public static void main(String[] args) throws InterruptedException {
new Test();
}
}
And not just the member 'x', but also there could be more members in class "Test" that I'd want to be able to perform operations on such as reading/writing.
Is this an okay structure to do so? If not, what should be fixed?
There are several problems with your code.
Consider this line:
aThread = new AThread(this);
It is always a bad idea to pass this somewhere in a constructor. And this has nothing to do with the threads... yet. The reason is that the 'somewhere' may call a method on this, and the method could be overridden in a subclass whose constructor wasn't called yet, and it may end up in disaster because that override may use some of the subclass fields that aren't initialized yet.
Now, when threads come into the picture, things get even worse. A thread is guaranteed to have correct access to a class instance that was created before the thread is started. But in your case, it isn't created yet, because the constructor is not finished yet! And it's not going to finish anywhere soon because of the infinite loop below:
while (true) {
aThread.queue.put("up");
}
So you have an object creation running in parallel to a startup of a thread. Java doesn't guarantee that the thread will see the initialized class in such case (even if there was no loop).
This is also one of the reasons why starting threads in constructors is considered a bad idea. Some IDEs even give a warning in such cases. Note that running infinite loops in constructors is probably a bad idea too.
If you move your code into a run() kind of method and do new Test().run() in main(), then you code will look fine, but you are right to worry about
However, what if at some point in the future I decide to do operations
on x in the main thread?
The best idea is for the main thread to forget about the object right after it is passed to the thread:
public static void main(String[] args) throws InterruptedException {
AThread aThread = new AThread(new Test());
aThread.start();
while (true) {
aThread.queue.put("up");
}
}
However, what if at some point in the future I decide to do operations on x in the main thread? Or just simply reading from x. What if both the other thread and the main thread want to read x at the same time?
Any time you are sharing information between two threads, you need to provide for memory synchronization. In this case, if you make int x be volatile int x then your code should work fine. You should read the Java tutorial on the subject.
However, if the thread is doing more complex operations, as opposed to just setting or getting x, then you may need to make the method be synchronized or otherwise provide a mutex lock to make sure that the 2 threads don't overlap improperly.
For example, if you need to increment the value of x, a volatile won't help since increment is actually 3 operations: get, increment, and set. You could use a synchronized lock to protect the ++ or you should consider using an AtomicInteger which handles incrementAndGet() methods in a thread-safe manner.
#Segey's answer gives some great feedback about the rest of your code. I'll add one comment about this code:
while (true) {
aThread.queue.put("up");
}
You almost never want to spin like this. If you want to do something like this then I'd add some Thread.sleep(10) or something to slow down the adding to the queue or make the queue bounded in size. It is likely that you are going to run out of memory spinning and creating queue elements like this.
Related
I understood that reading and writing data from multiple threads need to have a good locking mechanism to avoid data race. However, one situation is: If multiple threads try to write to a single variable with a single value, can this be a problem.
For example, here my sample code:
public class Main {
public static void main(String[] args) {
final int[] a = {1};
while(true) {
new Thread(new Runnable() {
#Override
public void run() {
a[0] = 1;
assert a[0] == 1;
}
}).start();
}
}
}
I have run this program for a long time, and look like everything is fine. If this code can cause the problem, how can I reproduce that?
Your test case does not cover the actual problem. You test the variable's value in the same thread - but that thread already copied the initial state of the variable and when it changes within the thread, the changes are visible to that thread, just like in any single-threaded applications. The real issue with write operations is how and when is the updated value used in the other threads.
For example, if you were to write a counter, where each thread increments the value of the number, you would run into issues. An other problem is that your test operation take way less time than creating a thread, therefore the execution is pretty much linear. If you had longer code in the threads, it would be possible for multiple threads to access the variable at the same time. I wrote this test using Thread.sleep(), which is known to be unreliable (which is what we need):
int[] a = new int[]{0};
for(int i = 0; i < 100; i++) {
final int k = i;
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(20);
} catch(InterruptedException e) {
e.printStackTrace();
}
a[0]++;
System.out.println(a[0]);
}
}).start();
}
If you execute this code, you will see how unreliable the output is. The order of the numbers change (they are not in ascending order), there are duplicates and missing numbers as well. This is because the variable is copied to the CPU memory multiple times (once for each thread), and is pasted back to the shared ram after the operation is complete. (This does not happen right after it is completed to save time in case it is needed later).
There also might be some other mechanics in the JVM that copy the values within the RAM for threads, but I'm unaware of them.
The thing is, even locking doesn't prevent these issues. It prevents threads from accessing the variable at the same time, but it generally doesn't make sure that the value of the variable is updated before the next thread accesses it.
so I got this horses race and when a horse getting to the finishing line, I invoke an arrival method. Let's say I got 10 threads, one for each horse, and the first horse who arrives indeed invoking 'arrive':
public class FinishingLine {
List arrivals;
public FinishingLine() {
arrivals = new ArrayList<Horse>();
}
public synchronized void arrive(Horse hourse) {
arrivals.add(hourse);
}
}
Ofc I set the arrive method to synchronized but I dont completely understand what could happen if it wasnt synchronized, the professor just said it wouldn't be safe.
Another thing that I would like to understand better is how it is decided which thread will after the first one has been finished? After the first thread finished 'arrive' and the method get unlocked, which thread will run next?
1) It is undefined what the behaviour would be, but you should assume that it is not what you would want it to do in any way that you can rely upon.
If two threads try to add at the same time, you might get both elements added (in either order), only one element added, or maybe even neither.
The pertinent quote from the Javadoc is:
Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.)
2) This is down to how the OS schedules the threads. There is no guarantee of "fairness" (execution in arrival order) for regular synchronized blocks, although there are certain classes (Semaphore is one) which give you the choice of a fair execution order.
e.g. you can implement a fair execution order by using a Semaphore:
public class FinishingLine {
List arrivals;
final Semaphore semaphore = new Semaphore(1, true);
public FinishingLine() {
arrivals = new ArrayList<Horse>();
}
public void arrive(Horse hourse) {
semaphore.acquire();
try {
arrivals.add(hourse);
} finally {
semaphore.release();
}
}
}
However, it would be easier to do this with a fair blocking queue, which handles the concurrent access for you:
public class FinishingLine {
final BlockingQueue queue = new ArrayBlockingQueue(NUM_HORSES, true);
public void arrive(Horse hourse) {
queue.add(hourse);
}
}
This code came from sample OCP/SCJP
I'm not really sure why Printx() is called before run().
and why this is guaranteed?
public class ConstructorOrRun extends Thread {
private int x = 2;
public ConstructorOrRun() throws Exception {
x = 5;
start();
}
public void printX() throws Exception {
x = x - 1;
System.out.print(x);
}
public void run() {
x *= 2;
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
new ConstructorOrRun().printX();
}
}
I don't think 'guaranteed' is the right word here. In practice the printx will be likely to finish first, because starting a new thread takes a huge amount of time relative to the time taken for the current running thread to do a litle arithmetic, get the (uncontended) lock for the console and write to it.
It is a race condition, though, and it would be a really bad idea to rely on either thing happening first. If a program runs enough times all kinds of interleavings may happen. There's no guarantee which thing will happen first here, it would be better to avoid making assumptions.
There's another issue. The constructor is called by the main thread, initializing x, then starting a new thread. The new thread modifies x in the run method, but there isn't anything requiring making the contents of x visible to the new thread. Making x volatile would make its contents visible.
And yet another issue: the arithmetic operations take multiple steps to be executed and can be interfered with by the other thread. It's not just a question of which operation will happen first, they could be interleaved. Fixing this would require locking or using atomicInteger.
ConstructorOrRun() returns immediately, on the main thread, and then printX() is invoked.
There's no guarantee that calling start() in the constructor will cause run() to start, let alone finish (on a different thread), before the constructor returns. In fact, I'd be surprised if it did.
StringBuffer can handle multiple threads through synchronization If your text can changes, and will be accessed from multiple threads, use a StringBuffer because StringBuffer is synchronous.
Can anyone explain me when does the Multithreading happen? Do we create threads in our program implementing runnable interface or extending Thread class or is it OS based?.
The threading can happen any number of ways. If you are creating threads (e.g. extends Thread) or if you are creating objects that get passed off to a threading model of some kind (e.g. implements Runnable) or even if you just have code somewhere that handles something like events (e.g. a callback function). How the threads are created isn't important. In any case, when you have something like this:
public String someMethod()
{
StringBuilder b = new StringBuilder();
b.append("Some Method");
return(b.toString());
}
You know that is thread safe. Any access to the StringBuilder's append() method doesn't need to by synchronized. However, if you have something like this (just an example):
public class Test
{
StringBuffer b;
public Test()
{
b = new StringBuffer();
}
public String someMethod()
{
b.append("Some Method");
return(b.toString());
}
}
Here, you can see that more than one "thread" of execution could call someMethod(), and since they would all be access the StringBuffer, it needs to be synchronized. It could be the case that only one thread ever calls the method at any one given time, but the way this is written doesn't prohibit 2 threads calling it at the same time. If a StringBuilder is used (not thread safe) you're likely to run into problems.
It is either 'implementing runnable' and 'extending Thread'
If the resource (here StringBuffer ) is shared among the multiple thread (java processes) / Assume that StringBuffer is defined in non monitored scope (i.e outside synchronize{} block )
In that case multiple threads will not wait in que to access the StringBuffer instance as there is no monitor/ or lock needs to be obtained to modify the instance.
More info on java concurrency
Let's take your program is not capable of doing two different actions/events at the same time. Then you need to think about Threads. From a logical point of view, multithreading means multiple lines of a single program. In this case, the operating system is treating the programs as two separate and distinct processes
Java's creators have graciously designed two ways of creating threads: implementing an interface and extending a class. A simple case cane be when you are having a Log file and multiple threads are logging errors or warnings and writing to that log file.
A dog's sense of smell is polymorphic. If the dog smells a cat, it will bark and run after it. If the dog smells it food, it will salivate and run to its bowl. The sense of smell is at work in both situations. The difference is what is being smelled, that is , the type of data operated upon by the dog's nose!
Let's dive with an example:
// Here is our main class.
class ThreadTest2 {
public static void main(String args[]){
Thread thread1 = new Thread(new MyClass("thread1: "));
Thread thread2 = new Thread(new MyClass("thread2: "));
thread1.start();
thread2.start();
boolean thread1IsAlive = true;
boolean thread2IsAlive = true;
do {
if (thread1IsAlive && !thread1.isAlive()) {
thread1IsAlive = false;
System.out.println("Thread 1 is dead.");
}
if (thread2IsAlive && !thread2.isAlive()) {
thread2IsAlive = false;
System.out.println("Thread 2 is dead.");
}
} while (thread1IsAlive || thread2IsAlive);
}
}
// Here is our class which implements runnable interface.
class MyClass implements Runnable {
static String message[] = { "Java", "is", "hot,", "aromatic"};
String name;
public MyClass(String id){
name = id;
}
public void run(){
for(int i=0;i<message.length;++i) {
randomWait();
System.out.println(name+message[i]);
}
}
void randomWait(){
try {
Thread.currentThread().sleep((long)(3000*Math.random()));
} catch (InterruptedException x) {
System.out.println("Interrupted!");
}
}
}
This program creates two threads of execution, thread1 and thread2, from the MyThread class. It then starts both threads and executes a do statement that waits for the threads to die. The threads display the Java is hot, aromatic. message word by word, while waiting a short, random amount of time between each word. Because both threads share the console window, the program's output identifies which threads were able to write to the console at various times during the program's execution.
You need to explicitly create extra Threads via, for example, the Runnable interface or the Thread class for multithreading to be a concern. This also holds true for certain Java EE situations, where the JVM creates extra threads.
If the OS uses extra threads in the background, it, and not you, is responsible for thread safety, so this is nothing you need to worry about.
You can read more in the Concurrency section of the Java Tutorials.
(Problem solved, solution below)
I have 2 classes: Equip and Command. The equip is an equipment that run commands, but I need it to be able to run only 1 command at the same time.
A command is a thread, that executes on the run() function, while Equip is a normal class that don't extend anything.
Currently I have the following setup to run the commands:
Command class:
#Override
public void run() {
boolean execute = equip.queueCommand(this);
if (!execute) {
// if this command is the only one on the queue, execute it, or wait.
esperar();
}
// executes the command.....
equip.executeNextCommand();
}
synchronized public void esperar() {
try {
this.wait();
} catch (Exception ex) {
Log.logErro(ex);
}
}
synchronized public void continue() {
this.notifyAll();
}
Equip class:
public boolean queueCommand(Command cmd) {
// commandQueue is a LinkedList
commandQueue.addLast(cmd);
return (commandQueue.size() == 1);
}
public void executeNextCommand() {
if (commandQueue.size() >= 1) {
Command cmd = commandQueue.pollFirst();
cmd.continue();
}
}
However, this is not working. Basically, the notify() isn't waking the command thread, so it'll never execute.
I searched about the wait and notify protocol, but I couldn't find anything wrong with the code. I also tried calling the wait() directly from the queueCommand() method, but then the execution of the queueCommand stopped, and it also didn't do what it was supposed to do.
Is this approach correct and I'm missing something or this is completely wrong and I should implement a Monitor class to manipulate the concurrent threads?
EDIT: I solved the problem using another completely different approach, using Executors, thanks to #Gray.
Here's the final code, it might help someone someday:
Equip class:
private ExecutorCompletionService commandQueue = new ExecutorCompletionService(Executors.newFixedThreadPool(1));
public void executeCommand(Command cmd, boolean waitCompletion) {
commandQueue.submit(cmd, null);
if (waitCompletion) {
try {
commandQueue.take();
} catch (Exception ex) {
}
}
}
In the Command class I just have a method to encapsulate the equip's execute method.
The boolean waitCompletion is used when I need the result of the command at the same time, and instead of calling a new thread to execute it, I just execute and wait, pretending that it's executing on the same thread. This question contains a good discussion on this matter: When would you call java's thread.run() instead of thread.start()?. And yes, this is a case where it's useful to call .run() instead of .start().
There are a large number of race conditions that exist in your code if Command.run() is called from multiple threads. Unless this is some sort of homework question where you have to implement the code yourself, I would highly recommend using one of the Java Executors which were added in 1.6. In this case the Executors.newSingleThreadExecutor() is what you need to limit the number of running background tasks to 1. This will allow an unlimited number of tasks to be submitted to the ExecutorService, but only one of those tasks will be executing at any one time.
If you need the thread that is submitting the tasks to block when another task is already running then you would use something like the following. This sets up a pool of a maximum of 1 thread and uses a SynchronousQueue which blocks until the worker thread consumes the job:
final ExecutorService executorServer =
new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
But if that was the case then you would just call the task directly inside of a synchronized block and you wouldn't need the ExecutorService.
Lastly, for any new concurrency programmer (of any language) I would recommend that you take the time to read some documentation on the subject. Until you start recognizing the concurrent pitfalls inherent in threading even the simplest set of classes, it will be a frustrating process to get your code to work. Doug Lea's book is one of the bible's on the subject. My apologies if I have underestimated your experience in this area.
I think you should not have "synchronized" on the esperar method. That will block using the object instances as the locking object. Any other thread that attempts to wait will block AT ENTRY TO THE METHOD, not on the wait. So, the notifyAll will release the one thread that got into the method first. Of the remaining callers, only one will proceed with a call to esperar, which will then block on the wait(). Rinse and repeat.
ExectutorService is the way to go. But if you want to do-it-yourself, or need to do something fancier, I offer the following.
I gather than this whole thing is driven by Equip's queueCommand, which might be callled from any thread anywhere at any time. For starters, the two methods in Equip should by synchronized so commandQueue does not get trashed. (You might use ConcurrentLinkedQueue, but be careful with your counts.) Better still, put the code in each method in a block synchronized by queueCommand.
But further, I think your two classes work better combined. Switching Command to a simple Runnable, I'd try something like this:
class Equip {
private Object queueLock = new Object(); // Better than "this".
private LinkedList<Runnable> commandQueue = new LinkedList<Runnable>();
private void run() {
for (;;) {
Runnable cmd = equip.getNextCommand();
if (cmd == null) {
// Nothing to do.
synchronized (queueLock) { queueLock.wait(); }
}
else
cmd.run();
}
}
// Adds commands to run.
public boolean queueCommand( Runnable cmd ) {
synchronized (queueCommand) { commandQueue.addLast( cmd ); }
synchronized (queueLock) {
// Lets "run" know queue has something in it if it
// is in a wait state.
queueLock.notifyAll();
}
}
private Runnable getNextCommand() {
synchronized (queueCommand) { return commandQueue.pollFirst(); }
}
}
You'll need to catch some exceptions, and figure out how to start things up and shut them down, but this should give an idea of how the wait and notify work. (I'd look for some way to know when "run" was not waiting so I could skip synching on queueLock in queueCommand, but walk before you run.)