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.
Related
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);
}
}
I have the following piece of code. It has two objects, namely MultiThreadingTest, and the ThreadB object. When we say synchronized(b), what does it mean exactly? Can the 'main' thread get a lock on b before ThreadB finishes it's execution? I can't understand the significance of monitor object in the synchronized block.
package threads;
class MultiThreadingTest
{
public static void main(String[] args)
{
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b)
{
System.out.println("Current thread : "+ Thread.currentThread().getName());
try
{
System.out.println("Waiting for b to complete...");
b.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Total = "+b.total );
}
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this)
{
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i=0;i<100;i++)
{
total = total + i;
}
notify();
}
}
}
Think of it like the child's game, whoever holds the [whatever object] gets to speak. Whoever holds the monitor object gets to execute in computing terms.
The monitor is the object you are locking upon, at any given time, only one thread accesses code protected by a synchronization block per monitor object. The object itself is arbitrary and doesn't hold much weight onto synchronization (though you have to watch out for reassigning variables as well as null references). Also, JB Nizet raises a good point here on synchronizing on a Thread object since many internal VM methods do that, you can cause bazaar, hard to detect bugs and deadlocks.
Two threads entering different synchronization blocks locking on different monitors will execute concurrently, analogous to two separate groups of people playing/enacting the "who ever holds to xxx gets to speak" game. Locking on this is just a convenient way to manifest a single lock synchronization without creating additional lock objects.
In your case, ThreadB b is the same object pointed to as this from within the ThreadB class meaning that only one thread can enter any of your defined synchronization blocks at once. The order is highly dependent on which thread ran first, the thread scheduler and even the underlying system.
The main reason for monitor objects is so that complex thread-safety mechanisms can be realized. Imagine a system where every synchronization block is single thread access (i.e. at any time, any thread enters a synchronization block will hold every other thread in the whole VM trying to enter a sync block) not only will this cause a massive performance slowdown, it just doesn't make sense. Why should two unrelated application modules lock on each other if they share no data and never interact?
The solution of course is to have one module use one (or several) monitor objects that are unrelated/unassociated with the other module, so both can execute concurrently independent of each other (assuming this is the desired behavior).
To further clarify, you could write:
class MultiThreadingTest{
public static void main(String[] args){
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b.lock){
System.out.println("Current thread : "+ Thread.currentThread().getName());
try{
System.out.println("Waiting for b to complete...");
b.lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total = " + b.total );
}
}
}
class ThreadB extends Thread{
public final Object lock = new Object();
int total;
public void run(){
synchronized(lock){
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i = 0; i < 100; i++){
total = total + i;
}
lock.notify();
}
}
}
to exactly the same effect as the code you've used (even better, since it resolves the conflict with Thread.join() and other methods).
synchronized(this) means that you won't be able to enter this block of code if another thread is inside a block of code that is also synchronized on the object referenced by this.
synchronized(b) means that you won't be able to enter this block of code if another thread is inside a block of code that is also synchronized on the object referenced by b.
They thus do the exact same thing. The only difference is the object that is used to lock.
Note that waiting, synchronizing and notifying on an object of type Thread is a really really bad idea. It confuses things, and will lead to unwanted behavior because other methods (join() for example) also use the Thread as a monitor.
As per my understanding, no. The 'this' object within the run() method and the 'b' object in the main() method are the same.
Hence it would not be possible for the 'main' thread to acquire the lock until the thread completes execution.
Also the notify() within the run() method seems to be redundant in this case since its at the end of the method and the lock on the monitor would be relinquished any how.
PS: Do look around for similar questions that may already have been asked in the forum. They may help in providing additional understanding.
public class Computation extends Thread {
private int num;
private boolean isComplete;
public Computation(int nu) {
num = nu;
}
public void run() {
System.out.println("Thread Called is: " + Thread.currentThread().getName());
}
public static void main(String... args) {
Computation [] c = new Computation[4];
for (int i = 0; i < 3; i++) {
c[i] = new Computation(i);
c[i].start();
}
}
}
My Question is in main function we are creating every time a new Computation object on which the thread is being started then why we need to snchrnoized the run method? As we know for every different class object 'this' reference is different so we don't need to synchronize.
Also in another Example:
public class DiffObjSynchronized implements Runnable {
#Override
public void run() {
move(Thread.currentThread().getId());
}
public synchronized void move(long id) {
System.out.print(id + " ");
System.out.print(id + " ");
}
public static void main(String []args) {
DiffObjSynchronized a = new DiffObjSynchronized();
/**** output ****/
// 8 9 8 9
new Thread(a).start();
new Thread(new DiffObjSynchronized()).start();
}
}
Here is second example just like first we create a Thread on 2 different instances of class. Here we synchronize the move() method but by definition:
"two different objects can enter the synchronized method at the same time"
Please share your feedback?
If I understand you correctly, your question is: "Why is the move method synchronized?"
The answer is: it shouldn't be, for two reasons:
It doesn't access any fields, so there is nothing that could be corrupted by having many threads inside that method at once.
Each thread gets a different instance of the object, and thus a different lock. So the synchronized modifier makes no difference. Each thread can still enter its own instance's move method because they have separate locks.
You only need to synchronize when you have some data which is being shared between threads, and at least one thread is modifying that data.
Your threads are operating on different objects since you create a new instance for each thread. The intrinsic lock used by synchronized belongs to the instance. So the synchronized methods entered by your threads are guarded by different locks.
You need to understand how synchronization works.
Threads take a 'lock' on the object on which you are synchronizing when they enter the synchronized block. If you have a synchronized method then in that case the object becomes the 'this' instance. Now, no 2 threads can take a lock on the same object at the same time. object locks are mutex based in philosophy so only once thread can hold the mutex at a time. When the thread holding the lock exits the synchronized method or the block, it releases the mutex and thus the object lock becomes available to other threads to request lock on.
This link explains the concepts excellently. It has pictures about disassembled byte code which shows how threads take and leave locks and why 2 threads on 2 different object dont block each other.
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.
What are the possible ways to make code thread-safe without using the synchronized keyword?
Actually, lots of ways:
No need for synchronization at all if you don't have mutable state.
No need for synchronization if the mutable state is confined to a single thread. This can be done by using local variables or java.lang.ThreadLocal.
You can also use built-in synchronizers. java.util.concurrent.locks.ReentrantLock has the same functionality as the lock you access when using synchronized blocks and methods, and it is even more powerful.
Only have variables/references local to methods. Or ensure that any instance variables are immutable.
You can make your code thread-safe by making all the data immutable, if there is no mutability, everything is thread-safe.
Secondly, you may want to have a look at java concurrent API which has provision for providing read / write locks which perform better in case there are lots of readers and a few writers. Pure synchronized keyword will block two readers also.
////////////FIRST METHOD USING SINGLE boolean//////////////
public class ThreadTest implements Runnable {
ThreadTest() {
Log.i("Ayaz", "Constructor..");
}
private boolean lockBoolean = false;
public void run() {
Log.i("Ayaz", "Thread started.." + Thread.currentThread().getName());
while (lockBoolean) {
// infinite loop for other thread if one is accessing
}
lockBoolean = true;
synchronizedMethod();
}
/**
* This method is synchronized without using synchronized keyword
*/
public void synchronizedMethod() {
Log.e("Ayaz", "processing...." + Thread.currentThread().getName());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
System.out.println("Exp");
}
Log.e("Ayaz", "complete.." + Thread.currentThread().getName());
lockBoolean = false;
}
} //end of ThreadTest class
//For testing use below line in main method or in Activity
ThreadTest threadTest = new ThreadTest();
Thread threadA = new Thread(threadTest, "A thead");
Thread threadB = new Thread(threadTest, "B thead");
threadA.start();
threadB.start();
///////////SECOND METHOD USING TWO boolean/////////////////
public class ThreadTest implements Runnable {
ThreadTest() {
Log.i("Ayaz", "Constructor..");
}
private boolean isAnyThreadInUse = false;
private boolean lockBoolean = false;
public void run() {
Log.i("Ayaz", "Thread started.." + Thread.currentThread().getName());
while (!lockBoolean)
if (!isAnyThreadInUse) {
isAnyThreadInUse = true;
synchronizedMethod();
lockBoolean = true;
}
}
/**
* This method is synchronized without using synchronized keyword
*/
public void synchronizedMethod() {
Log.e("Ayaz", "processing...." + Thread.currentThread().getName());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
System.out.println("Exp");
}
Log.e("Ayaz", "complete.." + Thread.currentThread().getName());
isAnyThreadInUse = false;
}
} // end of ThreadTest class
//For testing use below line in main method or in Activity
ThreadTest threadTest = new ThreadTest();
Thread t1 = new Thread(threadTest, "a thead");
Thread t2 = new Thread(threadTest, "b thead");
t1.start();
t2.start();
To maintain predictability you must either ensure all access to mutable data is made sequentially or handle the issues caused by parallel access.
The most gross protection uses the synchronized keyword. Beyond that there are at least two layers of possibility, each with their benefits.
Locks/Semaphores
These can be very effective. For example, if you have a structure that is read by many threads but only updated by one you may find a ReadWriteLock useful.
Locks can be much more efficient if you choose your lock to match the algorithm.
Atomics
Use of AtomicReference for example can often provide completely lock free functionality. This can usually provide huge benefits.
The reasoning behind atomics is to allow them to fail but to tell you they failed in a way you can handle it.
For example, if you want to change a value you can read it and then write its new value so long as it is still the old value. This is called a "compare and set" or cas and can usually be implemented in hardware and so is extremely efficient. All you then need is something like:
long old = atomic.get();
while ( !atomic.cas(old, old+1) ) {
// The value changed between my get and the cas. Get it again.
old = atomic.get();
}
Note, however, that predictability is not always the requirement.
Well there are many ways you can achieve this, but each contains many flavors. Java 8 also ships with new concurrency features.
Some ways you could make sure thread safety are:
Semaphores
Locks-Reentrantlock,ReadWriteLock,StampedLock(Java 8)
Why do u need to do it?
Using only local variable/references will not solve most of the complex business needs.
Also, if instance variable are immutable, their references can still be changed by other threads.
One option is use something like a SingleThreadModel, but it is highly discouraged and deprecated.
u can also look at concurrent api as suggested above by Kal