I am using java.
I have an instance a of class A which has a public method foo() running and 2 other threads - threadB and threadC, all running at the same time.
here's class A
public class A {
int val = 0
public void foo(int incValue) {
a += incValue;
}
public static void main (String arg[]) {
MyThread a = new MyThread(this);
new Thread(a).start();
MyThread b = new MyThread(this);
new Thread(b).start();
}
}
here's the thread definition for threadB and threadC:
public class MyThread implements Runnable {
A main = null;
public MyThread(A main) {
this.main = main;
}
public callFoo(int incValue) {
main.foo(incValue);
}
#Override
public void run() {
//valToInc can be a value from a GUI form.
callFoo(valToInc);
}
}
If in threadB invokes callFoo(1) and threadC invokes callFoo(3) at the same time, then:
- Which thread will be able to call the method first?
- What is the result of the val in main class after both executions?
- Will the execution of the method for each thread happen concurrently or one after another?
There is absolutely no difference in how the JVM will invoke two methods "in parallel".
In other words: if you want to know what happens when a method is called, you can look here.
When a method is called "twice" in parallel, then that whole thing ... just happens twice!
Things become interesting when that method is making updates on that class, or in other objects! (like changing a field of your object, or appending a value to a list, ... )
You see, the real complexity of multi-threading is not about running some code in parallel. The real issue is what happens to "shared data".
If you find my answer to general; sorry - that is probably the best you can expect for such a generic question.
If [] threadB invokes callFoo(1) and threadC invokes callFoo(3) at the same time, then: - Which thread will be able to call the method first?
Threads run independently of each other. If there is no synchronization (there's none in your example), then any number of threads can be in calls to the same method at the same time.
Whenever a thread calls a method, it creates an activation record to hold all of the local variables and parameters of that method, and when several threads call the same method at the same time, each thread gets its own activation record. The threads can neither communicate with one another through the args and locals, nor can they interfere with one another's use of the args and locals.
They can, of course communicate and interfere with each other through any shared objects, including objects that may be referenced by the args or the locals.
Related
How main thread is able to access threadlocal of another thread? Although threadlocal of another thread gives another value in main thread than what it gives inside its own run method.
class MyThread13 extends Thread{
static int id =0;
ThreadLocal threadLocal = new ThreadLocal(){
public Integer initialValue(){
return ++id;
}
};
public MyThread13(String name){
super(name);
}
public void run(){
System.out.println(Thread.currentThread().getName()+" is executing with id :"+threadLocal.get());
}
}
public class MultiThreading13ThreadLocalB {
public static void main(String[] args) {
MyThread13 myThread13a = new MyThread13("Thread:1");
MyThread13 myThread13b = new MyThread13("Thread:2");
myThread13a.start();
myThread13b.start();
myThread13c.start();
// myThread13d.start();
System.out.println("Accessing threadlocal from main :"+myThread13a.threadLocal.get());
}
}
when threadlocal of another thread is being accessed from main thread , it should give null. But here it is giving some other value
Your example shows a confusion of ThreadLocal with what are simply member variables of Thread instances. The concepts are similar; both allow you to associate state with a Thread instance, but a ThreadLocal allows you to do it outside of the thread instance itself. As you've noted, a ThreadLocal lives up to its name -- when you call get and set on it, those values are specific to that thread, which is why trying to access another thread's state (as the main thread tries to do in your example) is not going to work.
ThreadLocals are sometimes helpful, but in day to day programming there is rarely a need for them. One kind of use case would be something like a server process that accepts an incoming request and associates some state with that request; if you don't want to change all of your method signatures to pass that state through, you could put it in a ThreadLocal. Usually there is a single ThreadLocal instance per JVM.
I know this is a bit naive question but I want to understand the basic working principle behind multi-threading in java. Consider the following code and say A is executed in Main thread and it starts execution of another worker thread ,defined in class B. I want to know that can B.func1 called from A and run method of B, be executed in parallel or not?
public class A {
public static void main(String[] args) {
B obj = new B();
obj.start();
obj.func1();
}
}
public class B extends Thread {
public B() {
//constructor
}
public void run() {
while(true) {
//do somethings
}
}
public void func1() {
//do someotherthings
}
}
There is no magic behind a method call. If you call method from a thread, it is called in exactly the same thread. So since obj.func1() is called from main, it will be run in the main thread. It doesn't matter which class it belongs to or whether or not it extends Thread.
The new thread starts by executing run. Everything called from run and so on will be executed in parallel to main.
It's important to understand the difference between a thread and a Thread.
A thread is an independent execution of your code. Often when we talk about how some method or another works we say things like, "It tests the variable x, and if x is less than zero it calls the foobar method..."
Ok, but what is the "it" in that sentence? It is not the method. Methods don't do anything. A method is just a list of instructions, like the list of chores that somebody left for their housemate to perform. The list doesn't do the chores, it's the housemate that does the work (or so we might hope).
The "it" is a thread. Threads are entities in the operating system that execute methods (i.e., they do the chores).
A Thread, on the other hand, is a Java object that your program can use to create and manage new threads. Your program creates a new Thread object by doing:
thread t = new Thread(...);
[Oops! See what I just did? It's not your program, that does the work, it's your program's main thread, or maybe some other thread in your program. It's an easy thing to forget!]
Anyway, it subsequently creates the new thread by calling t.start();
Once you understand all that, then Sergey Tachenov's answer becomes obvious: Calling the methods of a Thread object really is no different from calling methods of any other kind of object.
There are multiple issues with your code. I have corrected them and added one more statement to print Thread Name in func1().
Working code:
public class A {
public static void main(String args[]){
B obj = new B();
obj.start();
obj.func1();
}
}
class B extends Thread{
public B (){
//constructor
}
public void run(){
while(true){
//do somethings
}
}
public void func1 (){
//do someotherthings
System.out.println("Thread name="+Thread.currentThread().getName());
}
}
output:
Thread name=main
Since you are directly calling func1() from main method (A.java) , you will get Thread name = main in output.
If you add same print statement run() method, you will get output as : Thread name=Thread-0
Looking at the Thread constructors, I see there is one that takes single string parameter. I have the below code, which is kind of useless. I would like to know, how to make a fruitful use of this constructor and make something actually run
public class ThreadTest {
public static void main(String[] args) {
Thread t = new Thread("abc");
t.start();
System.out.println("Complete");
}
}
Or Is it not supposed to be used the way I demonstrated above?
I perfectly know how to write multiple threads and execute :), I am just trying to understand the correct use of this constructor? Should it only be used by calling super(name) by extending Thread and not by the way I am using it above.
The thread class in itself doesn't do all that much. You have to extend it or construct it around a runnable to make it perform a task when run. From the doc:
start(): "Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread."
run(): "If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns."
Therefore constructing a new thread in your fashion and starting it does nothing. One use of the Thread(String) constructor is in subclasses:
public class Worker extends Thread{
public Worker(int numb){
super("worker-"+numb);
}
#Override
public void run(){
//Stuff this thread actually does when run
//....
for(int i = 0; i < 10; i++)
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
To answer your second question in the comments, this is how you would write code that's executed in parallel. Consider the above class plus this main method:
public static void main(String[] args){
Worker w1 = new Worker(1);
Worker w2 = new Worker(2);
w1.start();
w2.start();
}
The run methods of w1 and w2 will be executed in parallel. The order of the print statements will vary between executions of the main method.
This particular constructor is used to specify the 'name' of a thread, which can later be used to distinguish between instances of a specific thread type.
From the official Java API documentation;
Thread
public Thread(String name)
Allocates a new Thread object. This
constructor has the same effect as Thread (null, null, name).
Parameters: name - the name of the new thread
Once you have allocated a Thread a name, you can call the getName() method on the Thread instance to return the name it was given when it was created. This can be useful for debugging or for distinguishing between instances of of the same Thread subclass type.
Extra Reading:
Official Guide - Defining and Starting a Thread
If you simply call this constructor you get a Thread which does nothing. Why? Look at the source code of java.lang.Thread. It has a private Runnable target; class variable. When you call this constructor, the target variable remains set to null (because this constructor simply sets the Thread's name).
Also, the run() method of java.lang.Thread looks like this:
public void run() {
if (target != null) {
target.run();
}
}
So it means that this run() method will do nothing as target is null.
In order to create/start a Thread which really does something useful read here:
The Java tutorial - how to run a thread?
I want to invoke different methods of class at same time.
I am creating 2 classes: Main- this instantiate object of Function and Function; this extends thread and has 2 methods.
Main.java
package ok;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Welcome to Threading");
Function f1 = new Function();
f1.start();
f1.calling();
f1.calling2();
}
}
Function.java
package ok;
public class Function extends Thread {
public void run() {
// TODO Auto-generated method stub
System.out.println("Run");
for(int y=140;y<170;y++){
System.out.println(y);
}
}
synchronized void calling(){
System.out.println("Let the game begin");
for(int y=40;y<70;y++) {
System.out.println(y);
}
}
synchronized void calling2(){
System.out.println("Let the game begin for me");
for(int y=0;y<40;y++) {
System.out.println(y);
}
}
}
How can I make the methods calling() and calling2() work at the same time?
If I start a thread it goes to run() call and doesn't have any return type. In my program, I need to have return value as a HashMap.
Do I need to create two classes which extends Threads and write logic of calling(), calling2() in run of those two classes?
Please suggest.
Your calling and calling2 methods are synchronized. The very essence of synchronized keyword is to prevent methods from executing concurrently. So in order to invoke both calling and calling2 in parallel you need to drop the synchronized keyword, at least from the method level.
Then, to invoke two methods at the same time, one Thread object is enough - one invocation can be executed in new thread, the other in the "current" thread, like this:
Thread thread = new MyThread();
thread.start(); // body of run() invoked in a new thread
thread.run(); // body of run() invoked in this thread, concurrently
It's better practice to produce separate Runnable objects for such use-cases, though. This has several advantages over the aformentioned approach:
it's more flexible - as the action is decoupled from the execution and encapsulated in a separate object, it becomes more like "data". If you ever feel the need to change computation strategy - e.g. use thread pool - it's trivial to do so with Runnable tasks. Not so with Thread extensions.
it's conceptually more sound, as subclassing a Thread suggests specializing its behaviour, while Runnables are more like "task containers" - favor composition over inheritance.
it's symmetric - no computation is treated differently, it's trivial to change e.g. which one executes where
Last, you seem to want to return something from your methods. For this, you might use a Future - a java concurrency utility class, representing asynchronous computation. In addition to Runnable advantages, it can return a value and offers features like cancellation and state querying.
You have to have the calls for running the methods inside your run() method.
Then you can just call the start() method and both methods will run. But that does not really solve the problem. What you need to do is create two threads and have each of them run their respective threads.
If I start a thread in a static block. Will the jvm wait for the thread to finish before it loads the class?
static {
System.out.println("static block");
DataRetrievalThread t = new DataRetrievalThread();
t.run();
}
The reason I'm trying this is because
I want to retrieve data from a server and it's taking way too long to get it. So to persist the data I want to retrieve it and store it in a file so that when the client asks for it - it does not need to make the call to the server to get the information.
If I start a thread in a static block. Will the jvm wait for the thread to finish before it loads the class?
Uh. Yes and no and NO.
First off, your code is not forking a thread. So as it is written it will hold up the class construction although technically the class is "loaded" before the static section runs. That's because you are executing the run() method directly in the current main thread. If you want to fork the thread then you should call t.start();.
If you actually fork the thread with t.start() then no, the thread will run in the background and will not hold up the class initialization.
You really should not be doing something like this. It's a tremendously bad pattern. If you explain what you are trying to accomplish, we should be able to really help.
If you are trying to pre-load data into your program then you should just run the load part early on in main() and don't park it in a static initializer in a class. But if you are running it in the main thread, holding up the program, I don't see why this is any faster then making the request on demand.
One thing to consider is to fork (with t.start()) a background thread to load the data and then have a class which holds the data. If the thread finishes in time then it will have pre-loaded the data. When the program needs the data, it should call the class to get it. If the thread hasn't finished it could do a countDownLatch.await(). When the thread finishes the download it could do countDownLatch.countDown(). So you will get some parallelism.
Something like:
public class DataLoader {
private volatile Stuff data;
private final CountDownLatch latch = new CountDownLatch(1);
// start the thread, called early in main()
public void init() {
// you pass in this so it can call setData
DataRetrievalThread t = new DataRetrievalThread(this);
t.start();
}
// called from the DataRetrievalThread
public void setData(Stuff data) {
this.data = data;
latch.countDown();
}
public Stuff getData() {
if (data == null) {
latch.await();
}
return data;
}
}
With run() you execute the method in the current thread, so after that the class will finish loading. You need to call start() to run the method in a new thread.