This #Synchronized commentary warns that:
Locking on this or your own class object can have unfortunate
side-effects, as other code not under your control can lock on
these objects as well, which can cause race conditions and other nasty
threading-related bugs.
Avoiding race conditions is exactly the reason why I need to use the synchronized modifier, but when I see a warning like this, I realize that I may be causing more harm than good by not knowing everything about the system for which I am programming...
In my particular situation, I need to make sure that a specific method of a WebView-subclass is not interrupted by a PictureListener.onNewPicture().
That method was written by me, but it is only invoked by a Runnable.run() via a timer handler.
What should I check before deciding that it is safe to use the synchronized modifier to make sure that that timer-invoked method is not interrupted by PictureListener.onNewPicture()?
The solution is to use a private object to serve as the object's lock, like this:
In the class definition:
private Object syncRoot=new Object();
or
private static Object syncRoot=new Object();
In your code:
synchronized(syncRoot){
// put your code here
}
The reason why race conditions can occur is that other code has access to the objects locked on. Locking only private objects solves this.
Have a property in a class that you syncronhize on, rather than synchronizing on this or WebView-subclass object.
Most of those side effects would mostly affect server systems. I don't think that on Android you will have much of the problem as there is not much other code that could touch your method.
Related
I read document, but I don't still get it.
The differences between this
private val myClass: MyClass = mockk(relaxed = true)
and this.
private val myClass: MyClass = mockk()
What I understood is if relaxed is true. Then, all the member fields or methods will return default values. Otherwise, not. is that correct understanding?
If so, setting always relaxed = true is better. But In this video, Ryan uses both. why?
https://youtu.be/60KFJTb_HwU?t=1015
If you're trying to call a mock method that doesn't know what to return and relaxed is not set to true you'll get an exception thrown. This is made, so tests are less likely to introduce unpredictable behavior, due to the default values returned by methods that the developer does not purposely mock.
In the linked video the view methods are probably never called, therefore no "relaxed" is necessary. You can also use "relaxedUnitFun", which works only for methods returning Unit, handy for example for classes responsible for events logging.
This is a double-edged weapon though, as "relaxing" everything deprives you of the security mechanism mentioned above. If this is what you want, you can also configure this globally, check https://mockk.io/#settings-file
To quote their documentation:
A relaxed mock is the mock that returns some simple value for all functions. This allows you to skip specifying behavior for each case, while still stubbing things you need. For reference types, chained mocks are returned.
source
I found the answer for Kotlin Lazy objects, using isInitialized() here: Kotlin: Check if lazy val has been initialised
But seems like dagger.Lazy doesn't have the same public method.
This is how I lazily inject using Dagger:
#Inject internal lateinit var someService: dagger.Lazy<SomeService>
How to check if someService is already initialized without calling someService.get() which will initialize it? Other than introducing a boolean flag and keep track of it ourselves..
Thanks!
There isn't a way to check; Lazy only has one method, get, making it a functional interface or "Single Abstract Method (SAM)" interface much like JSR330's Provider, Guava's Supplier, and JDK8 Supplier.
This abstraction is important, because in Dagger the definition of Lazy is more complicated and there is more than one implementation. For scoped bindings, the internal InstanceFactory itself implements Lazy, so the built in Provider<Lazy<T>> available for each T in the graph can be implemented using a class ProviderOfLazy that can simply return the internal Provider or InstanceFactory rather than creating a new wrapper instance. With that in mind, the instance of Lazy you interact with might be a shared one, so a hypothetical isInitialized might be ambiguous: Does it mark that the scoped binding was ever accessed, or just the local Lazy injection point you requested? Would that behavior change based on whether you mark the binding scoped or not in a faraway Module file? You could also imagine an implementation where every Lazy injection got its own instance, and each would locally track whether it had ever had its get called regardless of scoping. This is in contrast to Kotlin's Lazy, in which each instance wraps exactly one initializer function and consequently has less ambiguity.
Also, Kotlin's Lazy has multiple synchronization modes from which you can select, some of which have undefined behavior when called concurrently. isInitialized is never synchronized in any of those modes, so in a concurrent environment you might receive false while the value is in mid-construction, or it may even be fully constructed on a different thread and the value is simply not yet visible from the thread calling isInitialized.
If you need to be able to check on a Lazy-like status, you'll need to specify how wide you care about construction and how thread-safe you want the result to be, which is custom enough to warrant your own implementation.
I have this code which provides the logic of this solution, but I'm aware that collecting an instance from within the constructor is dangerous.
Does anyone know a better solution?
The goal is to collect all instances that are extending this class. My preferred solution is the one the uses as little resources as possible (libraries, cpu, ram) although I know that there will always be a tradeoff.
I've tried something with reflection, annotation, classpath search but non of them seemed to be the silver bullet.
class Parent{
private companion object{
var childs = arrayListOf<Parent>()
}
constructor(){
childs.add(this)
}
}
If the intention is to collect all instances you should anyway somehow get those instances upon their creation (will it be the constructor or factory method, if any). Also you should somehow store them (maybe LinkedList is a better choice). So your approach seems reasonable.
But remember that within this approach these instances will be linked from a static place, which means that they wouldn't be garbage collected. If you don't want that, you could store them using a WeakReference (more precisely a collection of WeakReference<Parent>'s).
I'm having trouble understanding the problem in this scenario.
I have a class used for Analytics Tracking, lets call it FlurryTracker,
it has 2 methods StartTrackingScreen(ScreenName) and StopTrackingScreen().
Now if I have a static var called screenName and each time start tracking screen is called screenName is reassigned.
startTrackingScreen(activity: Activity, screen: DhTracker.Screen<T>) {
screenName = screen.getName()
val lastScreen = Singleton.getLastScreen()
//If last screen is not same as current screen
FlurryAgent.logEvent(screenName, true)
}
}
override fun stopTrackingScreen() {
//New screen will start tracking before lastScreen tracking is stopped.
if (enabled) {
FlurryAgent.endTimedEvent(Singleton.getLastScreen()?.getName())
}
}
companion object{
lateinit var screenName : String
}
These methods are called in onStart() and onStop() in the app itself.
So with that being said, we are only tracking 1 screen at a time because when the user transitions to a new screen, onStop() and onStart() will be called.
So even though screenName is static, every time the lifecycle methods are called, that static var is being reassigned. Since a phone can't have 2 activites running at the same time, there will only be 1 instance of my tracker active at a time.
I don't really see the problem with using a static here, although I know best practices say that screenName should be created with every new instance. Am I looking at this the wrong way?
You can do that.
The two main patterns for something like this are static variables & methods or a singleton (That is often static so you can use it from different paths without passing it around). Both of these approaches are functionally identical.
The negatives for the static class are:
Difficult to test due to the fact that you have to replace the static method
Difficult to create a second instance
Difficult to pass around if you decide you want to (Some people like to know what classes are used by a given path for testing purposes)
These aren't that bad, you can live with them--however none of these issues exist if you use a singleton. You can easily pass it around, change it's behavior, convert it to use injection instead of the singleton pattern, …
So I can't really come up with a reason to ever use the static approach, there aren't any advantages.
Is it a good idea to specifically set the instance variables to null in onDestroy() callback of the activity? Something like this:
#Override
protected void onDestroy() {
super.onDestroy();
mClassVariable1 = null;
mClassVariable2 = null;
mClassVariable3 = null;
}
If I remember correctly from Java SE, any references that are isolated & not connected to a running program & can be garbage collected anyways. So does this make the above superfluous?
On the other hand, the lifecycle in mobile devices being different, would the above be a best-practice?
I know it cannot hurt to do it, but sometimes there are a number of class variable (references to indivudual UI elements etc), so I'd really like to know for my own understanding, what's really going on.
Thanks in advance!
You had it right when you said that the garbage collector will pick up references that are isolated. Specifically, any graph of references not connected to the execution thread will be collected. Because of this, there is no good reason to set your variables to null that I can see. Any advantages would be far outweighed by the code maintenance cost.