0

I know synchronized keyword makes method run only on single class at a time. But here is the problem.

I have a database class with methods e.g. insertAccount, updateSetting, etc. If I make insertAccount, updateSetting synchronized, each of them will be able to run only on one thread at a time.

If there was one method for whole database, it would be great, but there are not one. If one thread calls insertAccount and another thread calls updateSetting at the same time, it will go bad, right?

Because only one of these methods can be run at any time. So what do I do?

Is there a way to apply something like synchronized to the whole class? So that if 1st thread calls insertAccount and 2nd thread calls updateSetting at the same time, 2nd thread has to wait until 1st thread finishes accessing database.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
Gintas_
  • 4,940
  • 12
  • 44
  • 87
  • You should use a lock mechanism, such a semaphore – Luca Montagnoli Jul 17 '17 at 12:58
  • 1
    You should rely on (correct use of) database transactions with an appropriate transaction isolation level instead, then it will even work if you have multiple nodes hosting the (web) application (assuming they do use the same database). – Mark Rotteveel Jul 17 '17 at 13:09
  • Have a look at : https://stackoverflow.com/questions/442564/avoid-synchronizedthis-in-java?rq=1 – Ravindra babu Jul 17 '17 at 14:37

3 Answers3

6

The real answer here: step back and do some studying. You should not be using synchronized here, but rather look into a lock object that a reader/writer needs to acquire prior turning to that "DB class". See here for more information.

On the other hand, you should understand what transactions are, and how your database supports those. Meaning: there are different kinds of problems; and the different layers (application code, database) have different responsibilities.

You see, using "trial and error" isn't an approach that will work out here. You should spend some serious time studying the underlying concepts. Otherwise you are risking to damage your data set; and worse: you risk writing code that works fine most of the time; but fails in obscure ways "randomly". Because that is what happens when multiple threads manipulate shared data in an uncontrolled manner.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
1

You misunderstood how synchronized work.

If you mark two method of class by synchronized only one of them could be executed at any moment of time (except if you invoke wait).

Also note that if you have several instances of this class you can execute methods of different instances simultaneously.

talex
  • 17,973
  • 3
  • 29
  • 66
  • thanks, hmm, so you are saying it won't break? I have only 1 instance of Database class. You sure I don't need any lock mechanisms? – Gintas_ Jul 17 '17 at 13:01
  • 1
    Yes. It is enough to put `synchronized` on all method that access or modify object state. It isn't best approach, but it is simplest one. – talex Jul 17 '17 at 13:07
  • 2
    In general, just sticking `synchronized` on things without consideration or thought will not make it magically thread-safe or behave 'correctly'. – Mark Rotteveel Jul 17 '17 at 14:12
  • @MarkRotteveel Yes of corse. Doing anything "without consideration or thought" never lead to anything good. – talex Jul 17 '17 at 14:28
0

@Test(singleThreaded = true) Use above annotation above class and its tests will be run using a single thread even though you have used parallel="methods" in your testng.xml file

Manish Arya
  • 113
  • 1
  • 7