https://kotlinlang.org logo
#android
Title
# android
g

gildor

02/22/2023, 2:04 AM
I would say that (especially in context of Android, where you don’t want too block UI even because of locks) usually use coroutines Mutex, because anyway most of our business logic is suspend function based
But nothing wrong with usage of Java’s concurrency primitives like ReentrantLock
l

lawlorslaw

02/22/2023, 2:57 AM
Yeah so I was thinking about a reentrantlock but how do I guarantee only one instance of that object is created
g

gildor

02/22/2023, 3:06 AM
If you looking for replacement for synchronized block I don’t see a problem
synchronized already works only on object level, so it’s exactly the same as creating ReentrantLock as class-level property
l

lawlorslaw

02/22/2023, 3:14 AM
so this is the code i'm trying to refactor which results in this logic potentially being executed in parallel
Copy code
val lockObject = StarPrinterManager.manager ?: Object()
synchronized(lockObject) {
  // code to be executed inside the lock, to prevent multiple resources from calling this code      
}
and as it stands now if the
StarPrinterManager.manager
there will be a new object instance created everytime it hits that condition
g

gildor

02/22/2023, 3:28 AM
so lockObject just becomes ReentrantLock
Honestly I’m not that understand code snippet which you showed, if it a part of the same function, it doesn’t look that synchronization is correct
Usually you init lock on the class creation level to sync operation inside of your class. f you want global lock, just make declare it on top level, not as part of your class, so it will be a single lock per process of your application
👍 1
l

lawlorslaw

02/22/2023, 3:29 AM
Yes this code snippet is all inside a single function
g

gildor

02/22/2023, 3:30 AM
Then it not syncronized correctly
Multiple threads may execute “code to be executed inside the lock” simultaneusly if StarPrinterManager.manager is null
l

lawlorslaw

02/22/2023, 3:31 AM
So that's what I need to figure out, how do I declare it on the top level so it's a single lock per application?
g

gildor

02/22/2023, 3:31 AM
single lock per application is just val myResourceLock = ReentrantLock()
l

lawlorslaw

02/22/2023, 3:32 AM
But do I need to use dependency injection?
g

gildor

02/22/2023, 3:32 AM
It’s up to you
l

lawlorslaw

02/22/2023, 3:32 AM
Which class do I declare the reentrantlock instance?
g

gildor

02/22/2023, 3:32 AM
If you use DI which supports Singleton correctly, sure
Usually you do not declare lock public and instead you create a class, some repository for your resource, make this class Singleton (using DI, or just kotlin object) And expose functions to work with this resource, which under the hood use lock
l

lawlorslaw

02/22/2023, 3:41 AM
Okay I'll look into something like that
Was hoping to find some open source examples of this
g

gildor

02/22/2023, 4:17 AM
Of what exactly?
l

lawlorslaw

02/22/2023, 4:29 AM
Just that singleton pattern
g

gildor

02/22/2023, 4:37 AM
Do you use DI library? If so, it probably should already support it. If not, use Kotlin object declaration
👍 1
p

Petr Laštovička

02/22/2023, 11:05 AM
You can also try Kotlin Atomicfu
g

gildor

02/22/2023, 11:06 AM
I wouldn't recommend atomicfu until you really know what you are doing, it's very low level and exists as building block for multiplatform synchronization.
144 Views