IllegalMonitorStateException Thrown From Synchronized Block

Greetings,
We recently had a case where a java.lang.IllegalMonitorStateException was thrown from section of code (in activemq) that I'm 99.9% sure was properly synchronized. Has anyone ever seen this exception thrown when the object whose wait method is being called is currently owened (via. a synchronized block)?
The code that this exception occurred was in the backport-util-concurrent library. A get method (which is synchronized) call was made to a FutureTask instance which (eventually) calls Object.wait(). This call threw the exception. Below is the FutureTask code.
public synchronized Object get() throws InterruptedException, ExecutionException
  waitFor();
  return getResult();
private void waitFor() throws InterruptedException
  while (!isDone())
    wait();
}And the stack trace on the exception was:
ERROR - 21/2 08:56:41 - Failed to checkpoint a message store: java.lang.IllegalMonitorStateException - org.apache.activemq.store.journal.JournalPersistenceAdapter 395
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at edu.emory.mathcs.backport.java.util.concurrent.FutureTask.waitFor(FutureTask.java:267)
at edu.emory.mathcs.backport.java.util.concurrent.FutureTask.get(FutureTask.java:117)
at org.apache.activemq.store.journal.JournalPersistenceAdapter.doCheckpoint(JournalPersistenceAdapter.java:386)
at org.apache.activemq.store.journal.JournalPersistenceAdapter$2.iterate(JournalPersistenceAdapter.java:129)
at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:117)
at org.apache.activemq.thread.PooledTaskRunner.access$100(PooledTaskRunner.java:26)
at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:44)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:619)We are running Java 1.6 on solaris (64-bit). If anybody has any feedback on what might have caused this problem it would be appreciated.
Thanks,
Corey

There seem to be some difficult to reproduce bugs in JDK 6 relating to hotspot compilation (and maybe synchronization). A few threads worth checking out:
http://forum.java.sun.com/thread.jspa?threadID=5251785&tstart=0
http://forum.java.sun.com/thread.jspa?threadID=5262404&tstart=0
My own bug report (this one is reproducible): http://www.blinkenbyte.org/jvm/hotspot_bug_reviewid_1085121.html
Which reminds me, I need to get around to submitting an update to the report.. disabling HotSpot compilation on the problematic method made the problem go away in my case...
If at all possible to turn this into a test case, please do so and submit a bug report to Sun. Somehow Sun needs to pay attention to this problem, but I haven't even got a bug id on my problem despite it being 100% reproducible.

Similar Messages

  • [svn:bz-trunk] 21661: Avoid calling throwNotSubscribedException() from inside synchronized blocks to prevent potential issues acquiring the lock .

    Revision: 21661
    Revision: 21661
    Author:   [email protected]
    Date:     2011-07-21 06:21:07 -0700 (Thu, 21 Jul 2011)
    Log Message:
    Avoid calling throwNotSubscribedException() from inside synchronized blocks to prevent potential issues acquiring the lock.
    Checkin-Tests: Pass
    QA: Yes
    Doc: No
    Modified Paths:
        blazeds/trunk/modules/core/src/flex/messaging/client/FlexClient.java

  • How to catch Exception in backingbean which is thrown from the Model layer.

    Hi,
    JDev Ver: 11.1.1.2.0
    In my application there are two layer viewcontroller & model.
    In model layer I have created JPA service facade which does the database operation like persist, merge & remove entity.
    I am calling this service facade method from backing bean via below standard code.
    public static Object invokeMethod(String methodName, String mapKey,
    Object object){
    BindingContext bcx =
    DCUtil.getBindingContext((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest());
    JUFormBinding bc1 = (JUFormBinding)bcx.getCurrentBindingsEntry();
    FacesCtrlActionBinding reassignOperationBinding =
    (FacesCtrlActionBinding)bc1.findControlBinding(methodName);
    if (mapKey != null && object != null) {
    Map params = reassignOperationBinding.getParamsMap();
    params.put(mapKey, object);
    Object result = reassignOperationBinding.execute();
    return result;
    This is a static method which I am calling from backingbean to invoke service facade persist, merge or remove entity method
    I have written throws in all the methods signature of service facade.
    The exception which is thrown from the service facade are not comming back to backingbean catch block.
    Is there any way to catch this exception in backingbean.
    regards,
    devang

    Hi,
    2 things to check
    1 - does reassignOperationBinding has errors. You can check on the component
    2 - does the exception show on the binding layet. See the Fusion Developer guide for how to define an error handler on the databindings.cpx file
    Frank

  • NO EXCEPTION IS THROWN FROM THE PERSIST

    We are using Glassfish and MySQL. When we do a persist with a bad object/query, internal DB errors are NOT being reported back to the caller in any way, but Glassfish knows that the error occurred. Here is a schematic of the situation:
         Glassfish starts a CMP transaction and calls our bean
              Inside the bean we have code like this:
                   obj = (a new object that will cause a DB error when persisted)
                   try {
                        entityManager.persist(obj)
                   } catch (Throwable t) {
                        report to the user that the throwable happened
              bean returns
         Glassfish manages CMP transaction
    What we see is the following:
         - The persist has an internal failure and generates error messages in the Glassfish system.log file.
         - NO EXCEPTION IS THROWN FROM THE PERSIST, so the application code thinks that the persist completed correctly
         - At the end of the bean operation, Glassfish (correctly) rolls back the transaction.
    At the user level the result is that the request succeeds but nothing is put into the Database!
    We are not asking about the cause of the DB error. From reading the system log we know what happened and can fix it. Our problem is that problems in our field-deployed systems cannot be detected by the application code so failures cannot be reported to the user.
    The critical question is:
         Is there a way for the application code in the bean to see that an error occurred?
    By the way, we also have a secondary question: Why is the erroneous persist tried 6 times before deciding it won't work? Is there an option somewhere that says to try 6 times?
    The Exception as reported in the system log (only one copy of it) is included below.
    [#|2008-10-22T08:32:25.992-0400|WARNING|sun-appserver9.1|oracle.toplink.essentials.session.file:/opt/localVendors/glassfish/tems-glassfish-v1/domains/domain1/applications/j2ee-apps/im-app/im-ejb_jar/-local|_ThreadID=138;_ThreadName=p: thread-pool-1; w: 156;_RequestID=509e7043-21bb-410c-b795-19e9953afeec;|
    Local Exception Stack:
    Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0.1 (Build b04-fcs (04/11/2008))): oracle.toplink.essentials.exceptions.DatabaseException
    Internal Exception: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Column 'STATIONCODE' cannot be null
    Error Code: 1048
    Call: INSERT INTO <exact operation and table contents elided from this trace file>
         at oracle.toplink.essentials.exceptions.DatabaseException.sqlException(DatabaseException.java:311)
         at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:654)
         at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:703)
         at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:492)
         at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:452)
         at oracle.toplink.essentials.internal.sessions.AbstractSession.executeCall(AbstractSession.java:690)
         at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
         at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:214)
         at oracle.toplink.essentials.internal.queryframework.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:346)
         at oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:191)
         at oracle.toplink.essentials.internal.queryframework.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:205)
         at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:564)
         at oracle.toplink.essentials.queryframework.InsertObjectQuery.executeCommit(InsertObjectQuery.java:89)
         at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.performUserDefinedWrite(DatabaseQueryMechanism.java:750)
         at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.performUserDefinedInsert(DatabaseQueryMechanism.java:714)
         at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.insertObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:602)
         at oracle.toplink.essentials.queryframework.WriteObjectQuery.executeCommitWithChangeSet(WriteObjectQuery.java:162)
         at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:390)
         at oracle.toplink.essentials.queryframework.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:109)
         at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:628)
         at oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:555)
         at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:138)
         at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:110)
         at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2233)
         at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:952)
         at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:909)
         at oracle.toplink.essentials.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:269)
         at oracle.toplink.essentials.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:190)
         at oracle.toplink.essentials.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:2657)
         at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1044)
         at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:403)
         at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1126)
         at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:2443)
         at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:202)
         at oracle.toplink.essentials.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:131)
         at oracle.toplink.essentials.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:91)
         at com.sun.jts.jta.SynchronizationImpl.before_completion(SynchronizationImpl.java:99)
         at com.sun.jts.CosTransactions.RegisteredSyncs.distributeBefore(RegisteredSyncs.java:158)
         at com.sun.jts.CosTransactions.TopCoordinator.beforeCompletion(TopCoordinator.java:2548)
         at com.sun.jts.CosTransactions.CoordinatorTerm.commit(CoordinatorTerm.java:278)
         at com.sun.jts.CosTransactions.TerminatorImpl.commit(TerminatorImpl.java:249)
         at com.sun.jts.CosTransactions.CurrentImpl.commit(CurrentImpl.java:623)
         at com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:309)
         at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.commit(J2EETransactionManagerImpl.java:1030)
         at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:397)
         at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3792)
         at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3571)
         at com.sun.ejb.containers.MessageBeanContainer.afterMessageDeliveryInternal(MessageBeanContainer.java:1226)
         at com.sun.ejb.containers.MessageBeanContainer.afterMessageDelivery(MessageBeanContainer.java:1197)
         at com.sun.ejb.containers.MessageBeanListenerImpl.afterMessageDelivery(MessageBeanListenerImpl.java:79)
         at com.sun.enterprise.connectors.inflow.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:139)
         at $Proxy364.afterDelivery(Unknown Source)
         at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:324)
         at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:76)
         at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555)
    Caused by: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Column 'STATIONCODE' cannot be null
         at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:931)
         at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
         at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
         at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
         at com.mysql.jdbc.Connection.execSQL(Connection.java:3283)
         at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1332)
         at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1604)
         at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1519)
         at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1504)
         at com.mysql.jdbc.jdbc2.optional.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:840)
         at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:647)
         ... 53 more
    |#]

    This is because the persistent context is not synchronized with the database until the commit is being executed.
    You might 'force' this by calling entityManager.flush() right after the call to persist(...).
    Or you register a transaction synchronizer and check the transaction status on afeterCompletion().
    - Roy

  • This exception is never thrown from the try statement body

    try {
                   SimpleFileReader.openFileForReading("fileName.text");
              } catch (FileNotFoundException fnfe) {
                   System.out.println("");
              }This is part of a method, if that helps. In Eclipse I get the error message "Unreachable catch block for FileNotFoundException. This exception is never thrown from the try statement body." I saw another post similar to this one, but it's not quite clear what the solution is. Could anyone clarify for a beginner?
    Thanks

    It actually does if the file it's opening is not really a text file, or if it's read-protected. Or is that where I'm going wrong? I'm just trying to open the file's name(already in the field) and know that it is .text or will return the error.
    Edited by: meme_kun_345k on Jan 15, 2008 7:18 PM

  • Terminating enqueued threads at synchronized block

    Hi!
    I would really appreciate your opinions: :)
    The application desing:
    - I'm developing a web applicaction running on a Tomcat server.
    - The app is being developed using Struts and Spring.
    - Pages (presentation layer) are made of JSPs.
    - There are Spring beans (Services) that execute the business logic.
    - These Services are used by the Struts Actions.
    My problem case:
    1. When you submit myPage.jsp, MyAction.java's execute method is called.
    2. MyAction.java uses MyService.java's "process()" method to do some file processing that takes 2 to 3 hours to finish.
    3. This MyService.java is a singleton Spring bean.
    4. The call to process() method is synchronized on MyAction.java like this:
    public ActionForward execute(...) throws Exception {
         // Some code ...
         synchronized (this) {
              myService.process(...); // This method takes up to 3 hours to return
              // Some code ...
         return mapping.findForward("success");
    }As you can imagine, many requests (threads) will be enqueued at the synchronized keyword line. Because of this, I need to provide a cancelation functionality. This would be fired by a cancel button on myPage.jsp.
    So, if you tried to launch the so-long-process by the "Process" button on myPage.jsp and you received a "Waiting..." message at your screen (because the 3 hours process was launched by another client), you should be able to cancel your processing request (because you don't want to wait so much time to begin your file processing).
    I would really appreciate your opinions on which would be the best approach to achive this cancelation functionality.
    I'm sure there's a better way than the one I came up with: I could populate a class variable Map with "sessionId - Thread" (key - value) everytime a request arrives at the line before the synchronized block. Thus, when you clicked the Cancel button, MyAction.java would get the request's session id and then get the Thread it must terminate from the Map. Having the Thread instance, I could maybe call it's interrupt method.
    I don't think that's the best approach, but it's the only one I could thought about.
    Thank you very much for your time and opinions!

    Well, first thing I'd say is that if you use Spring, you'd be better off using it's own Controller architecture which is, to my mind, a lot more developed than Struts, especially now you can do pretty much the whole thing with @RequestMapping rather than XML.
    Having a web transaction wait for a long running server action is basically a bad idea. Rather you should have the web front end launch the file processing job and return immediately, probably showing a list of jobs to the user which may be queued, running or finished (for good or ill). One technique is to display a "background action in progress" page which submits a new transaction every few minutes to check if the job has finished yet (using a Javascript timer). If the job is still queued or running then this request displays the "in progress" page again, if finished it displays the result.
    Such a page could have a "Stop" button to abort the running job if feasible.
    I would suggest that you have a queue of background jobs, probably serviced by a ThreadPoolExecuter. The initial request simply builds a request object and queues it.
    Use a ContextListener object to create the queue and start the executer when the application starts, and close it down when the application is stopped,

  • Nested synchronized blocks on multiple objects without deadlock

    Is it possible? Here is an example problem that exhibits deadlock:
    public class SomeObject {
         public static class Foo {
              private int n = 0;
              public synchronized void p() {
                   n++;
                   if (n % 100 == 0)
                        System.out.print("f");
         public static class Bar {
              private int n = 0;
              public void p() {
                   n++;
                   if (n % 100 == 0)
                        System.out.print("b");
         public void doSomething1(Foo f, Bar b) {
              synchronized(f) {
                   synchronized(b) {
                        f.p();
                        b.p();
         public void doSomething2(Foo f, Bar b) {
              synchronized(b) {
                   synchronized(f) {
                        b.p();
                        f.p();
         public static void main(String[] args) {
              SomeObject so = new SomeObject();
              Foo f = new Foo();
              Bar b = new Bar();
              for (int i = 0; i < 100; i++)
                   (new MyThread(so, f, b)).start();
         public static class MyThread extends Thread {
              SomeObject so = null;
              Foo f = null;
              Bar b = null;
              public MyThread(SomeObject so, Foo f, Bar b) {
                   this.so = so;
                   this.f = f;
                   this.b = b;
              public void run() {
                   while (true) {
                        if (Math.random() > 0.5)
                             so.doSomething1(f, b);
                        else
                             so.doSomething2(f, b);
    }

    Well, playing with sinchronized code as to be done carefully.
    This is very important because de JVM does not break the deadlocks (like by throwing an exception in a deadlocked thread). so in the above example, once 2 of the threads do deadlock, the rest of the threads that are created in the main method loop will deadlock too.
    For that it is better to:
    a) use minimal sinchronized code, like in Foo.p, the method is sinchronized to have access to an internal variable.
    b) use layered sinchronization. If several components in a system have synchronized code (methods) or are used as monitors in synchronized blocks, then it is better to layer the monitor usage nesting and to eliminate circular dependencies (also it is good to minimize dependencies). This is similar to code dependency in which package circular dependency should be avoided. Though in this case it is critical.
    In the example given, the doSomething* methods generate circular dependency of monitors.
    If the desing is to have a 'transaction' in calling Foo.p() and Bar.p() from the doSomething* methods, then the usage of a 'grand-daddy' central lock would be a simple solution, like changing the doSomething* methods to:
    static public synchornized void doSomething*(Foo f, Bar b) {
    f.p();
    b.p();
    or
    public void doSomething*(Foo f, Bar b) {
    synchornized (SomeObject.class) {
    f.p();
    b.p();
    If there is no need of a 'transaction' in the calling of Foo.p() and Bar.p(), then the doSomething* methods should not have any type of synchronization, and the methods Foo.p() and Bar.p() should both be synchronized.
    Also a more complex scheme could be deviced in order to lower the contention on the SomeObject class monitor. Though for the example given, as it exists only one instance of both Foo and Bar, it is not needed.
    llongeri

  • Synchronized blocks: the best approach?

    I have a question concerning synchronization within a servlet. As I
              understand it, by default only one instance of a servlet will be
              instantiated by WebLogic. The impact of this is that if an instance
              variable is set in 'doGet', there is no guarantee that the value will be
              unchanged upon execution of 'doPost' (i.e. it is not "thread-safe").
              There are a few approaches to this problem, none of which are very
              appealing to me. If I utilize the "SingleThreadModel" interface, then I am
              guaranteed that the value will not change. However, this will occur at the
              expense of performance (isn't there a maximum of 5 instances?), especially
              if hundreds of users are concurrently attempting to access this same
              servlet. Even if I store a variable in the session, if the user can open
              multiple browser windows, then I could still run into a synchronization
              problem (since each window will share the same session).
              With this in mind (assuming that a user can open multiple browser windows
              and that I do not want to implement "SingleThreadModel"), is my only option
              to place synchronized blocks around the sections of code that I want
              protected?
              I appreciate any input. Thanks.
              

              It is possible to make this really messy - avoid that.
              Don't use intance variables, use only variables declared in the doGet method -
              each execution will have it's own variables and you won't have these problems.
              If you need data to persist from one call to the next, use the httpSession.
              If you need to manage separate browser windows - then put a hidden field or a
              parameter in the URL that identifies that window. Then store the data in the httpsession
              along with the window id -
              session.putValue("USERNAME_"+winId, username);
              Putting synchronized blocks doesn't really protect you from the multiple window
              problem - suppose a user does a search in one window - and the search results
              are stored in the http session. Then they do a second search in a second window
              - even if you protect the variables in a synchronize block - the second results
              will overwrite the first results. Then they start to page through what should
              be the first results in the first window - but they would see the second results.
              Mike Reiche
              Resume at http://home.earthlink.net/~mikereiche/resume.htm
              "Edward Mench" <[email protected]> wrote:
              > I have a question concerning synchronization within a servlet. As
              >I
              >understand it, by default only one instance of a servlet will be
              >instantiated by WebLogic. The impact of this is that if an instance
              >variable is set in 'doGet', there is no guarantee that the value will
              >be
              >unchanged upon execution of 'doPost' (i.e. it is not "thread-safe").
              >
              > There are a few approaches to this problem, none of which are very
              >appealing to me. If I utilize the "SingleThreadModel" interface, then
              >I am
              >guaranteed that the value will not change. However, this will occur
              >at the
              >expense of performance (isn't there a maximum of 5 instances?), especially
              >if hundreds of users are concurrently attempting to access this same
              >servlet. Even if I store a variable in the session, if the user can
              >open
              >multiple browser windows, then I could still run into a synchronization
              >problem (since each window will share the same session).
              >
              > With this in mind (assuming that a user can open multiple browser windows
              >and that I do not want to implement "SingleThreadModel"), is my only
              >option
              >to place synchronized blocks around the sections of code that I want
              >protected?
              >
              > I appreciate any input. Thanks.
              >
              >
              >
              >
              

  • Differentiating between same exception thrown from 2 different methods

    Suppose I have a class CodeDAO which has 2 methods who both throw SQLException
    public int getLocationCode(String locationName) throws SQLException;
    public int getDepartmentCode(String departmentName) throws SQLException;Now I have a business method in which I have to use both of the above DAO methods.
    public int process() {
       try {
          CodeDAO codeDAO = new CodeDAO();
          int locationCode = codeDAO.getLocationCode("NJ");
          int departmentCode = codeDAO.getDepartmentCode("Sales");
       catch (SQLException e) {
    }If SQLException is thrown how will I know if it is thrown by the getLocationCode method or getDepartmentCode method?
    What are the different choices I have in differentiating between same exception thrown from different methods? And which choice do you guys prefer?
    Thanks

    srhcan wrote:
    maheshguruswamy wrote:
    srhcan wrote:
    gimbal2 wrote:
    baftos wrote:
    Put each method invokation in its own try/catch block.Or in fact not use SQLException, but exceptions that are unique.So each DAO method has its own exception?
    public int getLocationCode(String locationName) throws GetLocationCodeException;
    public int getDepartmentCode(String departmentName) throws GetDepartmentCodeException;would not that means I have to create a lot of exception classes?
    Edited by: srhcan on Aug 9, 2012 2:54 PMLet me ask you this, what do you plan to do in the catch block? Do some sort of recovery? rollback? If it is just for logging purposes, I am pretty sure the exception message will give you enough information to find out where the error was.* I would like to give user a specific message based on which method fails. So if getLocationCode("NJ") fails the message can be: Unable to find code for Location "NJ". And if getDepartmentCode("Sales") fails the message can be: Unable to find code for Department "Sales".
    * I would like to print the exception's stacktrace in the log file.
    * I may do a rollback depending on if its an INSERT/UPDATE/DELETE statement.Well, in that case why not log it in the DAO methods themselves...inside getLocationCode and getDepartmentCode. Instead of trying to do the recovery/logging in the process method, do it in the individual dao methods. The calling classes should not be responsible for logging/recovery etc. It should be done in the DAO classes themselves and the DAO method should return an appropriate message/code to the consumer tier classes indicating the status of the transaction. Just my 0.02$.

  • Synchronized Block - Performance Issue

    Hi All,
    In my java class contains lot of synchronized methods...which in turn leads to performance issue....
    If i try to remove the synchronized methods...it leads to deadlock problem...
    Is there a way without removing the synchronized methods..to improve the performance...
    Please suggest any solution

    In my java class contains lot of synchronized methods...which in turn leads to performance issue....It causes sequentialization of critical sections of code so that they will execute correctly. You can't describe that as a performance problem unless you can show that a faster and correct implementation exists. It might: for example you could make yor synchronized blocks smaller, use concurrent data structures, etc. But what you can't do is compare it to the same code without synchronization and say it's slower. It is, but the observation has no meaning as the unsynch version isn't correct.
    If i try to remove the synchronized methods...it leads to deadlock problem...That isn't possible unless you didn't remove them all. Deadlocks result from acquiring locks in different orders.
    Is there a way without removing the synchronized methods..to improve the performance...Almost certainly. Post some code.

  • Performance of synchronized blocks on Linux much worse than on Windows

    Our application is a J2EE application currently deployed in WebLogic 6.1 which utilizes Oracle iFS as a content store. We access the iFS CMS through the api's provided in the cmdsk.jar. Our reference implementation has been Solaris and that's where most of our testing has been done so far. However, we recently began doing performance tests on Linux and ran into a strange problem. We found that we were not getting sufficient throughput and that this was coupled with underutilization of CPU resources on the Application Server (AS) node. With sufficient DB resources, which we had in this case, we expect to see full CPU utilization on the AS tier, so we knew something was wrong.
    A great deal of investigation revealed that all active threads were stuck at the same spot accessing an iFS cache. We found that this cache is implemented as a hashtable and accesses to hashtables are synchronized. However, we were not seeing the same problem on other platforms (Solaris and Windows) with dual CPU machines.
    In order to simplify things, we developed a test program to look at what we felt to be the root cause. This test program, which I will attach, essentially creates a hashtable then a number of threads (as specified by the user). These threads then use the hashtable.get method to access the hashtable concurrently and time how long it takes. The info is then returned at the end of the run.
    We ran a set of tests where we increased the number of threads from 1 to 100. This test was run once with Windows 2000 and once with Red Hat Linux 2.1 (kernel 2.4.9-e.12). The exact same hardware (dual 1.2 GHz PIII) was used in both cases. The results show that we were clearly able to reproduce the behaviour with this simple program. What these results show is that with one thread, access times are exactly the same for Windows and Linux. However, as we increase the number of threads, access times for Linux increase at a much greater rate than Windows. We also see underutilization of CPU resources on Linux while Windows uses all available.
    The first round of tests was run with Sun's JDK 1.3.1. We repeated the testing with 1.4.1 and found that there was no significant difference. I just tried it quickly with 1.4.2 and found the behaviour to be much the same. We also altered the program to use an unsynchronized hashmap instead of a hashtable and, as expected, performance on Linux was much better. CPU was fully utilized during the test.
    In order to determine if this was a problem "in the VM" or "in the kerenel", I tried repeating it with the JRocket VM provided by WebLogic. When running the same test with the JRocket VM, we saw performance roughly equivalent to what we saw with a hashmap and the Sun VM. That is, JRocket did not have the same problem as the Sun VM.
    So, it appears that there is something with the implementation of synchronized blocks in the Sun VM that is problematic, especially when compared to other platforms. It is likely that the problem lies in a combination of how the synchronization is implemention is based on the underlying operating system infrastructure. At this point, we don't really have a way to deal with the problem, aside from deploying multiple WebLogic nodes on the same 2 CPU physical AS node. Changes to the iFS infrastructure would help, but that's beyond our control. I've searched the bug database and have not seen mention of this problem. With the test program, it can be easily reproduced, but I wanted to run it by the folks on this list before submitting a bug.
    Thanks,
    Justin

    # File #1: Driver.java
    import java.io.*;
    import java.util.HashMap;
    import java.util.Hashtable;
    * Created on May 13, 2003
    * @author llai
    * Driver to test the access of hash table on various platforms.
    public class Driver
         public static void main(String[] args)
              * Obtain the following input values:
              * 1. Number of Elements
              *      - The number of elements in the hash table
              * 2. Size of Element
              * - The size of each element in the hash table
              * 3. Number of threads
              * - The number of concurrent threads in the test
              * 4. Focused Access
              * - Determines whether each thread access the same element or a random element
              * 5. Number of Accesses
              * - The number of accesses which each thread will complete before exiting
              * 6. Start offset
              * - The number of accesses at the beginning which will not be timed
              * 7. End offset
              * - The number of accesses at the end which will not be timed.
              * Initialize all input variables.
              * SET DEFAULT VALUES HERE...
              int numberOfElements = 10000;
              int sizeOfElement = 100;
              int numberOfThreads = 25;
              boolean focusedAccess = true;
              int numberOfAccesses = 1000000;
              int startOffset = 100000;
              int endOffset = 100000;
              boolean mapOrTable = false;
              * Input number of elements.
              try
                   BufferedReader in =
                        new BufferedReader(new InputStreamReader(System.in));
                   String tempInput;
                   boolean inputInvalid = true;
                   while (inputInvalid)
                        System.out.print(
                             "Enter a non-negative value for the number of elements to be in the hashtable: ");
                        tempInput = in.readLine();
                        if (tempInput.equals(""))
                             System.out.println("default value used.\n");
                             inputInvalid = false;
                        else
                             try
                                  numberOfElements = Integer.parseInt(tempInput);
                                  if (numberOfElements >= 0)
                                       inputInvalid = false;
                                  else
                                       System.out.println(
                                            "You entered a negative value for the number of elements. Try again.");
                             catch (NumberFormatException nfe)
                                  System.out.println(
                                       "You entered an invalid value for the number of elements. Try again.");
                   * Input size of elements.
                   inputInvalid = true;
                   while (inputInvalid)
                        System.out.print(
                             "Enter the size of each element in the hash table (ie. length of a string): ");
                        tempInput = in.readLine();
                        if (tempInput.equals(""))
                             System.out.println("default value used.\n");
                             inputInvalid = false;
                        else
                             try
                                  sizeOfElement = Integer.parseInt(tempInput);
                                  if (sizeOfElement >= 0)
                                       inputInvalid = false;
                                  else
                                       System.out.println(
                                            "You entered a negative value for the size of elements. Try again.");
                             catch (NumberFormatException nfe)
                                  System.out.println(
                                       "You entered an invalid value for the size of elements. Try again.");
                   * Input number of threads.
                   inputInvalid = true;
                   while (inputInvalid)
                        System.out.print(
                             "Enter the number of concurrent threads in the test: ");
                        tempInput = in.readLine();
                        if (tempInput.equals(""))
                             System.out.println("default value used.\n");
                             inputInvalid = false;
                        else
                             try
                                  numberOfThreads = Integer.parseInt(tempInput);
                                  if (numberOfThreads >= 0)
                                       inputInvalid = false;
                                  else
                                       System.out.println(
                                            "You entered a negative value for the number of threads. Try again.");
                             catch (NumberFormatException nfe)
                                  System.out.println(
                                       "You entered an invalid value for the number of threads. Try again.");
                   * Input focused access option.
                   inputInvalid = true;
                   while (inputInvalid)
                        System.out.print(
                             "Focused access? Determines whether each thread access the same element or a random element (y/n or blank for default): ");
                        String tempFocusedAccess = in.readLine();
                        if (tempFocusedAccess.equals("y"))
                             focusedAccess = true;
                             inputInvalid = false;
                        else if (tempFocusedAccess.equals("n"))
                             focusedAccess = false;
                             inputInvalid = false;
                        else if (tempFocusedAccess.equals(""))
                             System.out.println("default value used.\n");
                             inputInvalid = false;
                        else
                             System.out.println(
                                  "You entered an invalid input for focused access. Try again.");
                   * Input number of accesses.
                   inputInvalid = true;
                   while (inputInvalid)
                        System.out.print(
                             "Enter a non-negative value for the number of accesses each thread will complete: ");
                        tempInput = in.readLine();
                        if (tempInput.equals(""))
                             System.out.println("default value used.\n");
                             inputInvalid = false;
                        else
                             try
                                  numberOfAccesses = Integer.parseInt(tempInput);
                                  if (numberOfAccesses >= 0)
                                       inputInvalid = false;
                                  else
                                       System.out.println(
                                            "You entered a negative value for the number of accesses per thread. Try again.");
                             catch (NumberFormatException nfe)
                                  System.out.println(
                                       "You entered an invalid value for the number of accesses per thread. Try again.");
                   * Input start offset.
                   inputInvalid = true;
                   while (inputInvalid)
                        System.out.print("Enter the start offset: ");
                        tempInput = in.readLine();
                        if (tempInput.equals(""))
                             System.out.println("default value used.\n");
                             inputInvalid = false;
                        else
                             try
                                  startOffset = Integer.parseInt(tempInput);
                                  if (startOffset <= numberOfAccesses
                                       && startOffset >= 0)
                                       inputInvalid = false;
                                  else
                                       System.out.println(
                                            "You entered an invalid input for start offset. Try again.");
                             catch (NumberFormatException nfe)
                                  System.out.println(
                                       "You entered an invalid value for the start offset. Try again.");
                   * Input end offset.
                   inputInvalid = true;
                   while (inputInvalid)
                        System.out.print("Enter the end offset: ");
                        tempInput = in.readLine();
                        if (tempInput.equals(""))
                             System.out.println("default value used.\n");
                             inputInvalid = false;
                        else
                             try
                                  endOffset = Integer.parseInt(tempInput);
                                  if (endOffset <= numberOfAccesses && endOffset >= 0)
                                       inputInvalid = false;
                                  else
                                       System.out.println(
                                            "You entered an invalid input for end offset. Try again.");
                             catch (NumberFormatException nfe)
                                  System.out.println(
                                       "You entered an invalid value for the end offset. Try again.");
                   * Create a Hashtable, or a Hashmap?
                   inputInvalid = true;
                   while (inputInvalid)
                        System.out.print(
                             "Use HashMap or HashTable (enter m for HashMap, t for HashTable)? ");
                        String tempMapTable = in.readLine();
                        if (tempMapTable.equals("m"))
                             mapOrTable = true;
                             inputInvalid = false;
                        else if (tempMapTable.equals("t"))
                             mapOrTable = false;
                             inputInvalid = false;
                        else if (tempMapTable.equals(""))
                             System.out.println("default value used.\n");
                             inputInvalid = false;
                        else
                             System.out.println(
                                  "You entered an invalid input. Try again.");
              catch (IOException i)
                   System.out.println("IOException caught: " + i.getMessage());
              * End of obtaining input section. *****
              * Create a HashTable or HashMap of the size and distribution specified.
              Object hash;
              if (mapOrTable)
                   // create a HashMap
                   hash = new HashMap(numberOfElements);
              else
                   // create a HashTable
                   hash = new Hashtable(numberOfElements);
              char c[] = new char[sizeOfElement];
              for (int i = 0; i < numberOfElements; i++)
                   if (mapOrTable)
                        ((HashMap) hash).put(new Integer(i), new String(c));
                   else
                        ((Hashtable) hash).put(new Integer(i), new String(c));
              c = null; // Explicitly release c.
              * Create the specified number of threads.
              AccessorThread accessor[] = new AccessorThread[numberOfThreads];
              long seed;
              for (int i = 0; i < numberOfThreads; i++)
                   // Have a different seed for creating random number for each thread.
                   seed = System.currentTimeMillis() + 77 * i;
                   accessor[i] =
                        new AccessorThread(
                             hash,
                             numberOfElements,
                             focusedAccess,
                             numberOfAccesses,
                             startOffset,
                             endOffset,
                             seed);
                   // Start the thread.
                   accessor.start();
              * Make main wait for all threads to die before continuing.
              try
                   for (int i = 0; i < numberOfThreads; i++)
                        accessor[i].join();
              catch (InterruptedException ie)
                   System.out.println(
                        "InterruptedException caught: " + ie.getMessage());
              * Threads have now been run, so create a statistical report.
              System.out.println(
                   "The following settings were used for this test: \n"
                        + "Number of elements: "
                        + numberOfElements
                        + "\n"
                        + "Size of elements: "
                        + sizeOfElement
                        + "\n"
                        + "Number of threads: "
                        + numberOfThreads
                        + "\n"
                        + "Focused access: "
                        + focusedAccess
                        + "\n"
                        + "Number of accesses: "
                        + numberOfAccesses
                        + "\n"
                        + "Start offset: "
                        + startOffset
                        + "\n"
                        + "End offset: "
                        + endOffset);
              System.out.print("HashMap or HashTable: ");
              if (mapOrTable)
                   System.out.println("HashMap.\n");
              else
                   System.out.println("HashTable.\n");
              System.out.println("Statistic report: ");
              long avgTime;
              long avgTotalTime = 0;
              for (int i = 1; i <= numberOfThreads; i++)
                   avgTotalTime += accessor[i - 1].getAccessTime();
                   avgTime = accessor[i - 1].getAccessTime() / numberOfAccesses;
                   System.out.println(
                        "Thread "
                             + i
                             + "... "
                             + accessor[i
                             - 1].getStatus()
                             + " Total access time: "
                             + accessor[i
                             - 1].getAccessTime()
                             + " ms. Avg individual access time: "
                             + avgTime
                             + " ms.");
              avgTotalTime = avgTotalTime / numberOfThreads;
              // Make it an average over all threads.
              System.out.println(
                   "\nThe average total access time over all threads: "
                        + avgTotalTime
                        + " ms.");
    File#2: AccessorThread.java
    import java.util.Hashtable;
    import java.util.HashMap;
    import java.util.Random;
    * Created on May 13, 2003
    * @author llai
    * Threaded class that accesses a hashtable a certain number of times
    * and measures the access time for a certain number of accesses.
    public class AccessorThread extends Thread
         private Object hash;
         private int numberOfElements;
         private boolean focusedAccess;
         private int numberOfAccesses;
         private int startOffset;
         private int endOffset;
         private long seed;
         private long totalAccessTime;
         private String status;
         * Constructor
         * @param h the Hashtable or HashMap
         * @param keyToAccess the key to access for this thread
         * @param numberOfAccesses the number of access times
         * @param startOffset the start offset
         * @param endOffset the end offset
         public AccessorThread(
              Object h,
              int numberOfElements,
              boolean focusedAccess,
              int numberOfAccesses,
              int startOffset,
              int endOffset,
              long seed)
              this.hash = h;
              this.numberOfElements = numberOfElements;
              this.focusedAccess = focusedAccess;
              this.numberOfAccesses = numberOfAccesses;
              this.startOffset = startOffset;
              this.endOffset = endOffset;
              this.seed = seed;
              status = "Status: alive.";
         * @return the total access time.
         public long getAccessTime()
              return totalAccessTime;
         * @return the status of the thread.
         public String getStatus()
              return status;
         * @return the seed.
         public long getSeed()
              return seed;
         * Run method, accesses the hashtable at keyToAccess for
         * numberOfAccesses times, and measures the response time for
         * a certain number of those accesses.
         public void run()
              * Begin accessing the table, time only after startOffset accesses,
              * and only up to (numberOfAccesses - endOffset) accesses.
              * Access one value if focusedAccess on.
              * Access random values if focusedAccess off.
              Random numGenerator = new Random(seed);
              if (focusedAccess)
                   Object keyToAccess =
                        new Integer(numGenerator.nextInt(numberOfElements));
                   // Access without timing for the first startOffset accesses.
                   int i;
                   // Check if hash is a HashMap or Hashtable.
                   if (hash instanceof HashMap)
                        for (i = 0; i < startOffset; i++)
                             ((HashMap) hash).get(keyToAccess);
                        // Now start timing for the accesses.
                        long startTime = System.currentTimeMillis();
                        while (i < numberOfAccesses - endOffset)
                             ((HashMap) hash).get(keyToAccess);
                             i++;
                        long stopTime = System.currentTimeMillis();
                        totalAccessTime = stopTime - startTime;
                        // Finish accessing the remainder of endOffset times if endOffset is not >= (numberOfAccesses - startOffset).
                        while (i < numberOfAccesses)
                             ((HashMap) hash).get(keyToAccess);
                             i++;
                   else if (hash instanceof Hashtable)
                        for (i = 0; i < startOffset; i++)
                             ((Hashtable) hash).get(keyToAccess);
                        // Now start timing for the accesses.
                        long startTime = System.currentTimeMillis();
                        while (i < numberOfAccesses - endOffset)
                             ((Hashtable) hash).get(keyToAccess);
                             i++;
                        long stopTime = System.currentTimeMillis();
                        totalAccessTime = stopTime - startTime;
                        // Finish accessing the remainder of endOffset times if endOffset is not >= (numberOfAccesses - startOffset).
                        while (i < numberOfAccesses)
                             ((Hashtable) hash).get(keyToAccess);
                             i++;
              // Or else !focusedAccess, therefore access random values.
              else
                   * Get random keys to access and store in an array of Integer objects.
                   * Limit the array to 1000 integer objects.
                   int numberOfRandomInts = numberOfAccesses;
                   if (numberOfAccesses > 1000)
                        numberOfRandomInts = 1000;
                   Integer keysToAccess[] = new Integer[numberOfRandomInts];
                   for (int q = 0; q < numberOfRandomInts; q++)
                        keysToAccess[q] =
                             new Integer(numGenerator.nextInt(numberOfElements));
                   int i;
                   if (hash instanceof HashMap)
                        for (i = 0; i < startOffset; i++)
                             ((HashMap) hash).get(keysToAccess[i % numberOfRandomInts]);
                        // Now start timing for the accesses.
                        long startTime = System.currentTimeMillis();
                        while (i < numberOfAccesses - endOffset)
                             ((HashMap) hash).get(keysToAccess[i % numberOfRandomInts]);
                             i++;
                        // Stop the timing.
                        long stopTime = System.currentTimeMillis();
                        totalAccessTime = stopTime - startTime;
                        // Finish accessing the remainder of endOffset times if endOffset is not >= (numberOfAccesses - startOffset).
                        while (i < numberOfAccesses)
                             ((HashMap) hash).get(keysToAccess[i % numberOfRandomInts]);
                             i++;
                   else if (hash instanceof Hashtable)
                        for (i = 0; i < startOffset; i++)
                             ((Hashtable) hash).get(keysToAccess[i % numberOfRandomInts]);
                        // Now start timing for the accesses.
                        long startTime = System.currentTimeMillis();
                        while (i < numberOfAccesses - endOffset)
                             ((Hashtable) hash).get(keysToAccess[i % numberOfRandomInts]);
                             i++;
                        // Stop the timing.
                        long stopTime = System.currentTimeMillis();
                        totalAccessTime = stopTime - startTime;
                        // Finish accessing the remainder of endOffset times if endOffset is not >= (numberOfAccesses - startOffset).
                        while (i < numberOfAccesses)
                             ((Hashtable) hash).get(keysToAccess[i % numberOfRandomInts]);
                             i++;
              status = "Status: dead.";
    # File #3: run.sh
    echo Compiling the program...
    javac Driver.java AccessorThread.java
    export CLASSPATH=.
    echo Running the program...
    java Driver

  • Synchronized {blocks} are not synchronized ?

    Hi
    I have a stored procedure containing a method with a synchronized block :
    public class MyClass {
    private static Connection conn;
    public static void insert(String stringData) {
    synchronized (conn) {
    //LOGGING
    Date startTime = new java.util.Date();
    ... some code ...
    //LOGGING
    Date stopTime = new java.util.Date();
    }I suppose that when a lot of concurrent users wil use the stored procedure, the synchronized block of code will not be executed at the same time. But when I do that my log dates are overcrossing, that means concurrent execution.
    How can I make this code really synchronized ??
    thanks,
    Xavier
    null

    radiatejava wrote:
    You mentioned there could be some thread caching - can you pls explain why/how ? Since the threads are not accessing the variable directly and instead they are querying the object using a method, why would the method return some old value ? I understand in case of direct access to the variable, a thread can cache the variable. Do you mean to say that threads will also cache the methods ? Otherwise, how is it possible to return the stale value. I am not expecting a blind answer like XClass is not thread safe (I too agree to this) but some explanation on how caching is being done with method calls too.You are thinking of it in a wrong way. It doesn't matter if methods are cached or not, methods are just static code blocks. The important thing to understand is that all data can be cached unless it is volatile or synchronized. The integer "inside" XClass is data, and that data might get cached, so e.g. getVar can return the cached value. It doesn't need to read the value from main memory. The same applies to setVar, it doesn't need to update the value in main memory.

  • Actions after synchronized block happens-after?

    Hi,
    I'd like to verify that my intuitive understanding of synchronization is correct here. I've read the Java language specification but I couldn't find anything in my example. This relates very loosely to the double-checking (anti)pattern.
    My question is specifically: Say I have the code:
    public void method() {
        synchronized(anyObject) {
            actionA();
        actionB();
    }Does actionA() then have a happens-before relationship with actionB()?
    Thanks a lot!

    Thanks, but I'm not sure I understand.
    In my intuition, if a thread enters method(), it must wait (possibly no time at all) to acquire the anyObject lock before it can execute actionB() from a program perspective.
    What I read in the Java Specs was "If x and y are actions of the same thread and x comes before y in program order, then hb(x, y)." I wasn't sure if a synchronized block counts as an "action" in this case.
    Let me rephrase my question to be more specific. For any given thread that enters method(), can I be sure that actionA() on that thread will execute before actionB() on the same thread?
    Thanks!
    Edited by: bombax on Nov 8, 2012 10:11 AM

  • Java synchronized block question...

    If I have the following setup
    Hashtable h = ...; // there will only be one instance of h in the program's execution
    public void A(...) {
        syncronized(h) {
            // read or write from h
    public void B(...) {
        syncronized(h) {
            // read or write from h
    }I understand that only one of the synchronized blocks can execute at a time, however, does that also mean that each will be seeing the most recent copy of h? For instance, if I write something to h in A(), can I be guaranteed that when I read from h in B() that I will always read h directly from memory and not some cached value on that particular thread?
    Thanks!

    I was under the impression though that if thread 1 calls A() and adds something to h, then thread 2 calls B() and reads from h that thread 2 might have a different copy of h and not see the change that thread 1 made.
    I've been looking around and it seems that as long as you used synchronized as soon as the lock ends any changes to the object will be written to the main memory and also any time a lock starts the object is read from memory and not from that particular thread's cache (which may not contain the recent changes). Which I guess answers my original question, and Yes, each time one of those sync blocks starts they will have the most recent value of h, no matter what thread last modified it.

  • Is volatile necessary for variables only accessed inside synchronized block

    Hi,
    I am using ExecutorService to execute a set of threads. Then the calling thread needs to wait until all of them are done to reuse the thread pool to run another set of threads (so I can't use the ExecutorService.shutdown() to wait for all of the threads at this point). So I write a simple monitor as below to coordinate the threads.
    My question is: will it work? someone suggests that it might not work because it will busy spin on the non-volatile int which may or may not be updated with the current value from another thread depending on the whims of the JVM. But I believe that variables accessed inside synchronized blocks should always be current. Can anyone please help me to clarify this? Really appreciate it.
         * Simple synchronization class to allow a thread to wait until a set of threads are done.
         class ThreadCoordinator{
         private int totalActive = 0;
         public synchronized void increment(){
         totalActive++;
         notifyAll();
         public synchronized void decrement(){
         totalActive--;
         notifyAll();
         public synchronized void waitForAll(){
         while(totalActive != 0){
         try{
         wait();
         }catch (InterruptedException e){
         //ignore
         }

    Don't do that. Just save the Futures returned by the ExecutorService, and call get() on them all. This will only return when all the tasks have finished.

Maybe you are looking for