I am having an issue in Wicket, which I think may be more related to Java.
How to I handle a class that is serializable and has a running thread when it is serialized? I am losing state of the Thread when the class is serialized and then deserialized. My Thread reference is global, but when the class comes back the reference is null and the thread is still running. The List I am using and delcared inside the main class, and passed to the runnable class remains alive but no longer gets filled by the thread. The thread is still filling a List object but I am not seeing any updates in the main class...
I am using List batchLines = Collections.synchronizedList(new CopyOnWriteArrayList());
If your thread is running outside the page, so it should be better to reference it in your Application that is a singleton, e.g. use a map to put a unique id such as page hashCode. Just be careful about memory leaks.
Related
I have tried to read as much as I can about PyQt4's QThread and the idea of the worker thread. My question is, instead of building a QThread class to run everything in it from the def run(self): by the blahblah.start() command is there a way to create that individual thread class that has,say, 4 functions and you only call function 2 and then close that thread right after?
Subclassing QThread is a practice that is in general discouraged although often used. [see comment below]
In my opinion, this is a good example of how to use a thread in pyqt. You would create a Worker and a Thread, where the Worker is some general class of type QObject and the Thread is a QThread which you do not subclass. You'd then move the Worker to the Threat and start it.
self.worker = WorkerObject()
self.worker_thread = QtCore.QThread()
self.worker.moveToThread(self.worker_thread)
self.worker_thread.start()
Inside the Worker you can basically do whatever you want, it can have arbitrary many methods and so on.
The one big thing to keep in mind is that the Worker needs to be separate from the main loop. So the methods should not return anything that is used in the main loop (better not return anything at all) and the Worker's results should be collected using signals and slots.
self.button_start.clicked.connect(self.worker.startWork)
self.button_do_something_else.clicked.connect(self.worker.function2)
self.worker.signalStatus.connect(self.updateStatus)
Also make sure not to use any PyQt/GUI objects inside the worker, as this would also build a bridge between Worker and main loop through PyQt itself.
Java docs state following regarding synchronization of constructor:
Note that constructors cannot be synchronized — using the synchronized keyword with a constructor is a syntax error. Synchronizing constructors doesn't make sense, because only the thread that creates an object should have access to it while it is being constructed.
Warning: When constructing an object that will be shared between
threads, be very careful that a reference to the object does not
"leak" prematurely. For example, suppose you want to maintain a List
called instances containing every instance of class. You might be
tempted to add the following line to your constructor:
instances.add(this); But then other threads can use instances to
access the object before construction of the object is complete.
I am not able to understand this whole block. First it states that only the thread that creates an object has access to constructor. Then it warns of premature leak which may cause issues if other threads access the object before construction is complete. Are not these two things in contradiction. If only the creating thread can access the constructor then how can other threads prematurely access the object as it can only be accessed once contructor has run fully?
Any input would be of great help.
Imagine two threads that both have access to a global List (called "instances") holding instances of the class in question. Thread 1 continuously cycles through the list and does something with each instance. Thread 2 goes its own merry way, and occasionally constructs a new instance of the class. If the class would add itself to the List in its constructor (using instances.add(this)) Thread 1 would immediately get access to the instance and could do things with it before it is fully constructed, resulting in unpredictable behavior.
There may be a misunderstanding of the word "should". You wrote: "First it states that only the thread that creates an object has access to constructor. " However, the Java docs say: "only the thread that creates an object should have access to it while it is being constructed", which means that you should take care that only one thread has access to the object while it is being constructed.
I have a unit with an initialization and finalization section. This unit contains a complex object which is instantiated in the initialization and destroyed in the finalization. However, this object also contains an ADO Connection. That makes it an issue when using this across threads, because ADO is COM, and needs to be initialized for every thread.
This is how I currently handle this global object instance:
uses
ActiveX;
...
initialization
CoInitialize(nil);
_MyObject:= TMyObject.Create;
finalization
_MyObject.Free;
CoUninitialize;
end.
This only works on the main thread. Any other thread wouldn't be able to access it, and will return an exception CoInitialize has not been called.
How do I get around this to make this unit thread-safe? I would need a way to hook every creation/destruction of any thread created, and each thread would need to refer to a different instance of this object. But how to go about doing so?
Well, as you already say yourself, each thread needs to call CoInitialize separately. And in addition, each thread needs to have its own ADOConnection too.
I think you need to leave the idea of using the single global object/connection from that unit. Just repeat that object creation and destruction in each thread. When the thread types are different, then you could design a base thread class on top of them. If the object is too big (has overhead with regard to the thread) or does not 'fit' completely in the thread, then split the object design.
For now, your question sounds like just wanting to keep convenience, but if it is really necessary to centralize the ADO connection involvement, then maybe you could implement multi-cast events for the connection events of both main thread and the other threads. Logging in should not be a problem for successive connections: just store the login values and feed them to the threads.
While another design might be a better solution, you can declare _MyObject as threadvar to have a separate instance for each thread. In addition you can move the CoInitialize/CoUnitialize into the constructor/destructor of TMyObject.
I cannot give advice on when to create and free these instances as I have no idea how your threads are created and freed.
I always had this specific scenario worry me for eons. Let's say my class looks like this
public class Person {
public Address Address{get;set;}
public string someMethod()
{}
}
My question is, I was told by my fellow developers that the Address propery of type Address, is not thread safe.
From a web request perspective, every request is run on a separate thread and every time
the thread processes the following line in my business object or code behind, example
var p = new Person();
it creates a new instance of Person object on heap and so the instance is accessed by the requesting thread, unless and otherwise I spawn multiple threads in my application.
If I am wrong, please explain to me why I am wrong and why the public property (Address) is not thread safe?
Any help will be much appreciated.
Thanks.
If the reference to your Person instance is shared among multiple threads then multiple threads could potentially change Address causing a race condition. However unless you are holding that reference in a static field or in Session (some sort of globally accessible place) then you don't have anything to be worried about.
If you are creating references to objects in your code like you have show above (var p = new Person();) then you are perfectly thread safe as other threads will not be able to access the reference to these objects without resorting to nasty and malicious tricks.
Your property is not thread safe, because you have no locking to prevent multiple writes to the property stepping on each others toes.
However, in your scenario where you are not sharing an instance of your class between multiple threads, the property doesn't need to be thread safe.
Objects that are shared between multiple threads, where each thread can change the state of the object, then all state changes need to be protected so that only one thread at a time can modify the object.
You should be fine with this, however there are a few things I'd worry about...
If your Person object was to be modified or held some disposable resources, you could potentially find that one of the threads will be unable to read this variable. To prevent this, you will need to lock the object before read/writing it to ensure it won't be trampled on by other threads. The easiest way is by using the lock{} construct.
I have a QThread that contains a QUDPsocket (socket is member not local to QThread::run(), maybe I should change that from what I am reading). This QThread is instantiated in my QMainWindow class ie the GUI thread(I am not calling move to thread). Is it still safe to use waitForReadyRead or do I absolutly need to instantiate the QThread in main.cpp or call moveToThread() for it to be thread safe. I am getting intermittent double free exception inside the call to waitForReadyRead in the present way of doing it(sometimes I dont get it for days sometimes after 3 minutes).
Have a look at the Qt documentation for QUdpSocket. There is a note there explaining the class is reentrant. Also from the Qt documentation:
...a class is said to be reentrant if its member functions can be called safely from multiple threads, as long as each thread uses a different instance of the class.
Thus, to answer your question, it does not really matter what the parent of the QThread is, as long as you make sure that the QUdpSocket instance you are using is instantiated within the context of the thread you are using it in.