If join blocks the main thread, why it doesn't block in loop?
First of all:
The join() method of a Thread instance can be used to "join" the start of a thread's execution to the end of another thread's execution
That is a misconception: this has nothing to do with starting Threads. Join only does this: a running thread will wait until the other thread has ended.
When you do someThread.join()
, then the thread invoking that method will wait until someThread has ended!
But all the threads are joined in parallel.
Yes, because they are all done.
Your threads do all the exact same thing, so besides a few nanoseconds here or there (which are mostly invalidated due to the fact that writing to System.out effectively synchronizes stuff anyway) they all need the same amount of time.
So by the time you join the first thread ... the other two threads will be done. So the first call to join()
makes the "main" thread wait for the first thread to end, and the subsequent calls happen "instantly", because these threads are done, too.
In order to delay things, make the number of loops a parameter of your MultiThreading
class, and then ensure that your threads will require for different amounts of time. If Thread-0 does 10 loops, and Thread-1 goes 20, and the Thread-2 will do 30, you will see that each join does in fact wait for the corresponding thread to end.
Long story short: you start all your threads immediately, thus they instantly start running in parallel. The later join call simply delays the main thread from progressing, until each of the worker threads has ended.
join() blocks continuation of main thread
The entire point of join()
is to block until the other thread exits. Just get rid of it. Why'd you add it in the first place?
C# Thread.Join() blocks the main thread
You don't want to block and wait for the other thread to finish. That is what Thread.Join() does.
Instead you would want to perform a thread cancellation. MSDN Managed Thread Cancellation
The .join() method block UI thread even when called on a new thread
Since I see no evidence of any blocking operations, this is all you need:
fun btn(view: android.view.View) {
binding.firstText.text = ""
viewModelScope.launch {
delay(10_000)
val a = "I am the guy who comes 10 secs later\nDid you miss me?"
Log.d(TAG, "btn: $a")
binding.firstText.text = a
}
}
If you do intend to make blocking operations instead of that delay(10_000)
, then you can add this:
fun btn(view: android.view.View) {
binding.firstText.text = ""
viewModelScope.launch {
val a = withContext(Dispatchers.IO) {
blockingOperation()
"I am the guy who comes 10 secs later\nDid you miss me?"
}
Log.d(TAG, "btn: $a")
binding.firstText.text = a
}
}
Note there's the viewModelScope
, this won't work unless you're inside a ViewModel class. You can use GlobalScope
instead to try things out, but this is not a production-worthy solution as it leads to memory leaks at runtime whenever you trigger many such actions while the previous ones are in progress (and they will be because there's nothing cancelling them).
does threading.join() block the thread that's called it?
Your program starts the two threads before waiting for t1 and t2 to finish, that is why you have 30
before 19
in your console.
While the programs wait for t1 to finish, t2 is still running and printing to the console.
If for any reason you want to use multithreading and have t2
waiting for t1
to finish before starting, you can use the following code :
import threading
import time # Useful for adding some delay in order to visualize what is happening
def count(start, end):
for i in range(start, end):
print(i)
time.sleep(500) # Add some delay to see clearly what is happening
t1 = threading.Thread(target=count, args=[10, 20])
t2 = threading.Thread(target=count, args=[30, 40])
# This starts the two threads and wait for bot of them to finish
#t1.start()
#t2.start()
#
#t1.join()
#t2.join()
#
# This starts one thread and wait for it to finish before starting the other
t1.start()
t1.join() # We wait for t1 to finish
t2.start() # Then we start the second thread (t2)
t2.join()
NB : You can't start the same thread 2 times so make sure to comment/delete my part if you want to test the code with the 2 threads running at the same time.
EDIT : By program I mean main thread
Java Thread is blocked in join()
Without running it...
- The
close()
method holdslock
at the time it callsthread.join()
and waits onthread
(forever) thread
is waiting to reacquirelock
so cannot run
Both are now waiting on each other, this is a deadlock. Try moving the Thread.join()
after the synchronized
block:
public void close() throws InterruptedException {
run = false;
synchronized (lock) {
lock.notify();
System.out.println("Thread will join " + thread.isInterrupted());
}
thread.join();
System.out.println("Thread after join");
}
std::thread::join blocks indefinitely out of main
Yes it is the same bug as in the referenced link since your example also hangs on _Thrd_join
. You could be interrested in this question which contains a far more detailed analysis.
Thread.join blocks the main thread
You simply accumulate the threads in another container, then join
them one-by-one after they've all been created:
my_threads = []
for i in 1..100 do
puts "Creating thread #{i}"
my_threads << Thread.new(i) do |j|
sleep 1
puts "Thread #{j} done"
end
end
puts "#{Thread.list.size} threads"
my_threads.each do |t|
t.join
end
You also can't bind the thread to the i
variable because i
gets constantly overwritten, and your output will be 100 lines of "Thread 100 done"; instead, you have to bind it to a copy of i
, which I have cleverly named j
.
Related Topics
Will Uuid as Primary Key in Postgresql Give Bad Index Performance
How to Globally Configure Rspec to Keep the '--Color' and '--Format Specdoc' Options Turned On
How to Make Capybara Check for Visibility After Some Js Has Run
Rails Bundler Doesn't Install Gems Inside a Group
Hash['Key'] to Hash.Key in Ruby
Rails: Good Rspec2 Example Usage? (Also: Cucumber, Pickle, Capybara)
Ruby Method Calls Declared in Class Body
How to Build a Ruby Hash Out of Two Equally-Sized Arrays
The Command Rbenv Install Is Missing
Method_Missing Gotchas in Ruby
Rubocop Line Length: How to Ignore Lines with Comments
Tutorials or Screencasts on Building a Rest Web Service on Rails
Does Ruby Have a String.Startswith("Abc") Built in Method
Ruby: How to Concatenate Array of Arrays into One
Could Not Find a Valid Gem 'Rails' (>= 0) in Any Repository
How to Install Ruby on Rails in Windows