Going by the below code, I have two instances of class A - a1 and a2. And calling the method foo() on both the instances separately.
There is a synchronized block within the foo() method, which is locked on the calling object. Since it is an instance-level locking, both the methods should start executing at the same time because they are getting invoked from two separate instances. But, they are getting executed sequentially.
Is it because, both the instances getting invoked from the same Thread main?
Code changes: Made class A implements Runnable, renamed foo() to run(), forked a thread t from main, invoked a1.run() from main thread, invoked a2.run() from the thread t . Though the two A instances - a1 & a2 are getting called from two threads - main & thread t, the synchronized block(this) seems to be getting locked.
My understanding was the 'this' is referring to the calling Runnable instance which is different and even the threads are different. So, Thread.sleep should not make the other thread blocked. Then, why the two invocation of run's not happening in parallel?
Expected Output (should execute parallel)
main <time> Inside A.run
Thread-0 <time> Inside A.run
Thread-0 <time+4s> Exiting A.run
main <time+5s> Exiting A.run
Actual Output (executing sequentially)
main <time> Inside A.run
main <time+5s> Exiting A.run
Thread-0 <time+5s> Inside A.run
Thread-0 <time+9s> Exiting A.run
import java.time.*;
import java.time.format.DateTimeFormatter;
public class Test {
public static void main(String[] args) {
/*A a1 = new A(5000); A a2 = new A(4000);
a1.foo(); a2.foo();*/
A a1 = new A(5000); A a2 = new A(4000);
Thread t = new Thread(a2);
/*a1.run(); t.start();*/
t.start(); a1.run(); // <-- putting t.start() before a1.run() solves the issue
}
}
class A implements Runnable {
public long waitTime;
public A() {}
public A(long timeInMs) {
waitTime = timeInMs;
}
public void run() {
synchronized(this) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime time = LocalDateTime.now();
System.out.println(Thread.currentThread().getName() + " " + formatter.format(time) + " Inside A.run");
Thread.sleep(waitTime);
time = LocalDateTime.now();
System.out.println(Thread.currentThread().getName() + " " + formatter.format(time) + " Exiting A.run");
} catch (InterruptedException e) {}
}
}
}
You started to run a1 synchronously before starting the thread, of course you will get a1's output on the main thread because it won't have been able to reach the thread start statement until a1 is finished.
Try starting the thread running a2 first before you run a1 on the main thread, see what you get.
You should also be aware that thread scheduling may be delayed, and calling Thread#start does not immediately begin execution on a separate thread, but rather it queues it for the system thread scheduler. You might also want to consider using a synchronization device such as a CyclicBarrier in order to coordinate between the thread running a2 and the main thread running a1, else you may still get the exact same result even though it appears that you are starting the thread to run a1 before a2.
Is it because, both the instances getting invoked from the same
Thread main?
Yes. Calling Thread.sleep() is synchronous and will block the current thread for the duration unless interrupted. You're directly calling a1.foo() which will block the main thread for the duration, which is the result you're seeing. Create separate threads and call foo() in each of them and you'll see the behavior you're expecting.
Related
I want to give users the ability to customize the behavior of game objects, but I found that unity is actually a single threaded program. If the user writes a script with circular statements in the game object, the main thread of unity will block, just like the game is stuck. How to make the update function of object seem to be executed on a separate thread?
De facto execution order
The logical execution sequence I want to implement
You can implement threading, but the UnityAPI is NOT thread safe, so anything you do outside of the main thread cannot use the UnityAPI. This means that you can do a calculation in another thread and get a result returned to the main thread, but you cannot manipulate GameObjects from the thread.
You do have other options though, for tasks which can take several frames, you can use a coroutine. This will also allow the method to wait without halting the main thread. It sounds like your best option is the C# Jobs System. This system essentially lets you use multithreading and manages the threads for you.
Example from the Unity Manual:
public struct MyJob : IJob
{
public float a;
public float b;
public NativeArray<float> result;
public void Execute()
{
result[0] = a + b;
}
}
// Create a native array of a single float to store the result. This example waits for the job to complete for illustration purposes
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
// Set up the job data
MyJob jobData = new MyJob();
jobData.a = 10;
jobData.b = 10;
jobData.result = result;
// Schedule the job
JobHandle handle = jobData.Schedule();
// Wait for the job to complete
handle.Complete();
float aPlusB = result[0];
// Free the memory allocated by the result array
result.Dispose();
I am very new to Scala and following the Scala Book Concurrency section (from docs.scala-lang.org). Based off of the example they give in the book, I wrote a very simple code block to test using Futures:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
object Main {
def main(args: Array[String]): Unit = {
val a = Future{Thread.sleep(10*100); 42}
a.onComplete {
case Success(x) => println(a)
case Failure(e) => e.printStackTrace
}
Thread.sleep(5000)
}
}
When compiled and run, this properly prints out:
Future(Success(42))
to the console. I'm having trouble wrapping my head around why the Thread.sleep() call comes after the onComplete callback method. Intuitively, at least to me, would be calling Thread.sleep() before the callback so by the time the main thread gets to the onComplete method a is assigned a value. If I move the Thread.sleep() call to before a.onComplete, nothing prints to the console. I'm probably overthinking this but any help clarifying would be greatly appreciated.
When you use the Thread.sleep() after registering the callback
a.onComplete {
case Success(x) => println(a)
case Failure(e) => e.printStackTrace
}
Thread.sleep(5000)
then the thread that is executing the body of the future has the time to sleep one second and to set the 42 as the result of successful future execution. By that time (after approx. 1 second), the onComplete callback is already registered, so the thread calls this as well, and you see the output on the console.
The sequence is essentially:
t = 0: Daemon thread begins the computation of 42
t = 0: Main thread creates and registers callback.
t = 1: Daemon thread finishes the computation of 42
t = 1 + eps: Daemon thread finds the registered callback and invokes it with the result Success(42).
t = 5: Main thread terminates
t = 5 + eps: program is stopped.
(I'm using eps informally as a placeholder for some reasonably small time interval; + eps means "almost immediately thereafter".)
If you swap the a.onComplete and the outer Thread.sleep as in
Thread.sleep(5000)
a.onComplete {
case Success(x) => println(a)
case Failure(e) => e.printStackTrace
}
then the thread that is executing the body of the future will compute the result 42 after one second, but it would not see any registered callbacks (it would have to wait four more seconds until the callback is created and registered on the main thread). But once 5 seconds have passed, the main thread registers the callback and exits immediately. Even though by that time it has the chance to know that the result 42 has already been computed, the main thread does not attempt to execute the callback, because it's none of its business (that's what the threads in the execution context are for). So, right after registering the callback, the main thread exits immediately. With it, all the daemon threads in the thread pool are killed, and the program exits, so that you don't see anything in the console.
The usual sequence of events is roughly this:
t = 0: Daemon thread begins the computation of 42
t = 1: Daemon thread finishes the computation of 42, but cannot do anything with it.
t = 5: Main thread creates and registers the callback
t = 5 + eps: Main thread terminates, daemon thread is killed, program is stopped.
so that there is (almost) no time when the daemon thread could wake up, find the callback, and invoke it.
A lot of things in Scala are functions and don't necessarily look like it. The argument to onComplete is one of those things. What you've written is
a.onComplete {
case Success(x) => println(a)
case Failure(e) => e.printStackTrace
}
What that translates to after all the Scala magic is effectively (modulo PartialFunction shenanigans)
a.onComplete({ value =>
value match {
case Success(x) => println(a)
case Failure(e) => e.printStackTrace
}
})
onComplete isn't actually doing any work. It's just setting up a function that will be called at a later date. So we want to do that as soon as we can, and the Scala scheduler (specifically, the ExecutionContext) will invoke our callback at its convenience.
Just trying to understand threads and race condition and how they affect the expected output. In the below code, i once had an output that began with
"2 Thread-1" then "1 Thread-0" .... How could such an output happen? What I understand is as follows:
Step1:Assuming Thread 0 started, it incremented counter to 1,
Step2: Before printing it, Thread 1 incremented it to 2 and printed it,
Step3: Thread 0 prints counter which should be 2 but is printing 1.
How could Thread 0 print counter as 1 when Thread 1 already incremented it to 2?
P.S: I know that synchronized key could deal with such race conditions, but I just want to have some concepts done before.
public class Counter {
static int count=0;
public void add(int value) {
count=count+value;
System.out.println(count+" "+ Thread.currentThread().getName());
}
}
public class CounterThread extends Thread {
Counter counter;
public CounterThread(Counter c) {
counter=c;
}
public void run() {
for(int i=0;i<5;i++) {
counter.add(1);
}
}
}
public class Main {
public static void main(String args[]) {
Counter counter= new Counter();
Thread t1= new CounterThread(counter);
Thread t2= new CounterThread(counter);
t1.start();
t2.start();
}
}
How could Thread 0 print counter as 1 when Thread 1 already incremented it to 2?
There's a lot more going on in these two lines than meets the eye:
count=count+value;
System.out.println(count+" "+ Thread.currentThread().getName());
First of all, the compiler doesn't know anything about threads. It's job is to emit code that will achieve the same end result when executed in a single thread. That is, when all is said and done, the count must be incremented, and the message must be printed.
The compiler has a lot of freedom to re-order operations, and to store values in temporary registers in order to ensure that the correct end result is achieved in the most efficient way possible. So, for example, the count in the expression count+" "+... will not necessarily cause the compiler to fetch the latest value of the global count variable. In fact it probably will not fetch from the global variable because it knows that the result of the + operation still is sitting in a CPU register. And, since it doesn't acknowledge that other threads could exist, then it knows that there's no way that the value in the register could be any different from what it stored into the global variable after doing the +.
Second of all, the hardware itself is allowed to stash values in temporary places and re-order operations for efficiency, and it too is allowed to assume that there are no other threads. So, even when the compiler emits code that says to actually fetch from or store to the global variable instead of to or from a register, the hardware does not necessarily store to or fetch from the actual address in memory.
Assuming your code example is Java code, then all of that changes when you make appropriate use of synchronized blocks. If you would add synchronized to the declaration of your add method for example:
public synchronized void add(int value) {
count=count+value;
System.out.println(count+" "+ Thread.currentThread().getName());
}
That forces the compiler to acknowledge the existence of other threads, and the compiler will emit instructions that force the hardware to acknowledge other threads as well.
By adding synchronized to the add method, you force the hardware to deliver the actual value of the global variable on entry to the method, your force it to actually write the global by the time the method returns, and you prevent more than one thread from being in the method at the same time.
public class Test implements Runnable
{
public void run()
{
System.out.printf("%d",3);
}
public static void main(String[] args) throws InterruptedException
{
Thread thread = new Thread(new Test());
thread.start(); //line10
System.out.printf("%d",1);
thread.join();
System.out.printf("%d",2);
}
}
In the above code, at line 10 thread.start(); should spawn a new thread and hence run() should be called.Hence, Output should be 312 but instead on running the program, I got 132.
Main thread and new thread created are running in parallel , so if main thread reaches the line 11 first you will see 1 and then if new thread reaches its statement first you will get 3 and then 1
Start put thread to runnable mode, it does NOT mean call run method directly somewhere inside start, after start (), it counts on scheduler to finally run the thread, so 312 132 123 all are acceptable result.
The very nature of multi-threading is that you cannot usually guarantee or predict which line gets executed before another if they are being executed concurrently.
In this case it may be a little predictable however. Line 10 will need to access the memory (heap) allocation of the Test type, and then access the memory location of the run() method, and then execute the run() method, which then runs printf within that function.
Depending on what language you use, this may vary in optimization; but regardless of how well optimized that is, it will still always be slower than running the very next line after the thread.start() which prints 1 immediately after line 10 without waiting.
1.
i posted the question(About thread-safety of weak_ptr) several days ago,and I have the other related question now.
If i do something like this,will introduce a race condition as g_w in above example ?(my platform is ms vs2013)
std::weak_ptr<int> g_w;
void f3()
{
std::shared_ptr<int>l_s3 = g_w.lock(); //2. here will read g_w
if (l_s3)
{
;/.....
}
}
void f4() //f4 run in main thread
{
std::shared_ptr<int> p_s = std::make_shared<int>(1);
g_w = p_s;
std::thread th(f3); // f3 run in the other thread
th.detach();
// 1. p_s destory will motify g_w (write g_w)
}
2.As i know std::shared_ptr/weak_ptr derived from std::tr1::shared_ptr/weak_ptr, and std::tr1::shared_ptr/weak_ptr derived from boost::shared_ptr/weak_ptr, are there any difference on the implement,especially, in the relief of thread-safe.
The completed construction of a std::thread synchronizes with the invocation of the specified function in the thread being created, i.e., everything that happens in f4 before the construction of std::thread th is guaranteed to be visible to the new thread when it starts executing f3. In particular the write to g_w in f4 (g_w = p_s;) will be visible to the new thread in f4.
The statement in your comment // 1. p_s destory will motify g_w (write g_w) is incorrect. Destruction of p_s does not access g_w in any way. In most implementations it does modify a common control block that's used to track all shared and weak references to the pointee. Any such modifications to objects internal to the standard library implementation are the library's problem to make threadsafe, not yours, per C++11 § 17.6.5.9/7 "Implementations may share their own internal objects between threads if the objects are not visible to users and are protected against data races."
Assuming no concurrent modifications to g_w somewhere else in the program, and no other threads executing f3, there is no data race in this program on g_w.
#Casey
Firstly, I complete my code.
int main()
{
f4();
getchar();
retrun 0;
}
And I find some code in my visual studio 2013.