Is setting variables thread safe

Is it safe to set a variable in a multithreaded application?
public void setSomething(SomeObject object) {                                                                                                                                                                                                                       

there is no right answer to that question... as there is no single definition of thread safe... but generally it's dangerous to mutate an object in a multithreaded environment... hence all the complex locking.
go through threading tutorial: http://java.sun.com/docs/books/tutorial/essential/concurrency/

Similar Messages

  • Page flow controller - instance variable thread safe?

    I have page flow controller that is a subclass of org.apache.beehive.netui.pageflow.PageFlowController runing weblogic 921. The essence of my question is: is instance variable of page flow controller thread safe?
    Here are the details. I have an instance variable “status” that stores the status of the patient, which is stored in the request. It sets the status with after the patient status is retrieved from database. The set method is not synchronized.
    This works fine during normal test. But it failed during load test. Does a page flow controller instance shared among different requests? If so, how can I store the status for each request?
    Thanks,
    G T

    Hello
    You seem to put your question on the wrong forum
    Oracle Beehive and Apache Beehive are two different products...
    Have a look on http://beehive.apache.org
    Cheers
    Fred

  • Making set iterator thread-safe?

    Please consider:
    Set set = new HashSet();
    ........... // put stuff in "set"
    for(Iterator it = set.iterator(); it.hasNext(); ) {
      // <------ danger?
      Object s = (Object) it.next();
    }The only way to make this thread-safe??:
    Set set = new HashSet();
    synchronized(set) {
      for(Iterator it = set.iterator(); it.hasNext(); ) {
        Object s = (Object) it.next();
    }A different thread could, in theory, empty "set" between "it.hasNext()" and "it.next()"?
    So the entire (possibly huge/time consuming) "for" loop must be completely synchronized?
    thanks.

    rdkh wrote:
    DrClap wrote:
    Yes, that's correct. If you don't want anything else to monkey with the set while you're iterating over it, then obviously you have to lock everybody else out.what i was trying to explore was the one line of byte code between:
    (line A) it.hasNext()
    // <------- chance of the jvm swapping in a different thread and running its code that references to "set", and performs add/remove on "set" that effects the iterator
    (line B) it.next
    That chance has just got to be near 0. I mean, the lines are right next to each other in the same thread.It can happen so you have to assume it will. Thread safety is not about playing the odds. When the scheduler decides to switch a thread out, it does so. No matter what, it will be between to steps that are right next to each other. The fact that they're also "logically" close is 100% irrelevant.
    And of course, if it's a multicore or multi-CPU machine, you can get other threads coming in between those statements without this thread even being swapped out.
    And synchronizing might in theory hurt performanceBeing fast won't matter if you can't be sure it's right.
    Edited by: jverd on Jan 19, 2010 11:43 AM

  • SingleThreadModel-static variables thread safe?

    Hi..
    I have one servlet which implements SingleThreadModel.My servlet contains two static variables .
    public class MyServlet extends HttpServlet
    implements SingleThreadModel {
    private static String firstName="Umar hathab";
    private static StringBuffer lastName= new StringBuffer("Abdullah");
    I want to know whether this two variables will be thread safe? I know that static vars are shared in JVM..
    Please help me..
    Thanks in advance..
    A.Umar

    Hi heyad..
    Static variables are shared among the instances.When we create two instances of an object which contains a static variable,both the instances share the same static variable.So there will be data corruption when two instances operate on the static variable at the same time.So I feel static variables are not thread safe.What I want to know is whether static variables are thread-safe when implemented by SingleThreadModel..
    A.Umar

  • FIFO Thread Safe Variables

    Hi,
    I am currently trying to develop a Datalogger Application for a Fibre Optic link running at 250Mb/s. I have the code sorted that logs the data, but now have to try and store the data to disk.
    I need 3 Rx threads to keep up with the incoming data to ensure I dont get datalink errors on the card buffer, and I store the data into a Link List for processing by a Write Thread. To do this, I am trying to create a Thread Safe linked list variable as below :
    typedef struct list List;
    struct list {
     int  length;
     Node  *head;
     Node *current;
    DefineThreadSafeVar(List, SafeList);  
    List *SafeListPtr;  
    Then in the main function :
    InitializeSafeList();
    I then have an initialise Linked List function as follows:
    ViUInt32 LL_Initialise(void)
     SafeListPtr = GetPointerToSafeList();
     SafeListPtr = (List*)malloc(sizeof(List));
     SafeListPtr->length = 0;
     SafeListPtr->head = SafeListPtr->current = NULL;
     ReleasePointerToSafeList();
     return 0;
    This appears to initialise the linked list correctly, setting the head and current pointers to NULL.
    But, when i call the following function :
    ViUInt32 LL_GetLength()
     ViUInt32 length;
     SafeListPtr = GetPointerToSafeList();     <- ******************
     length = SafeListPtr->length;
     ReleasePointerToSafeList();
     return (length);
    They line I have marked causes the head and current pointers to return to Uninitialised and then causes a Run Time error when try to use them.
    If you have followed that.....Any ideas?
    Thanks
    Stuart

    Well, I suppose you can create an intermediate buffer in the receiving function:
    create an array of your List structure
    read a record from the queue: if in the correct order, stream it to disk
    if out of order, fill a record of the array
    when you receive the next record in the correct order:
    put it to disk
    sort array content (e.g. with QuickSort passing an appropriate comparison function) and see if and how many records in the buffer can be put to disk
    You may want to design a different algorithm to decide when to sort so that you don't have too much data in the intermediate buffer: sorting on every record may cause too much overhead in your application and a growing buffer of record left to write to disk.
    Please keep posting: this multi-producer-one-consumer framework is an interesting schema to study! ;-)
    Proud to use LW/CVI from 3.1 on.
    My contributions to the Developer Zone Community
    If I have helped you, why not giving me a kudos?

  • About the thread safe variable

    Hello,
    I have make 2 projects, the first is using to initialize the enviroument an  loading  some modules, and the 2nd using to execute a special work. In the first project, I use the DeclareThreadSafeScalarVar macro to define the handle of a file, I think the file handle can be shared between 2 processes, and each process can access data by the file handle.It is worth mentioning that the 2nd process loading is by the CreateProcess() API. My question is : if the safe variable is initialized in the first process, can I use the safe variable in the second process? Do I need to reinitialize the safe variable in the 2nd process? Thanks.
    David

    David,
    Thread safe variables are only going to work for threads within the same process. Windows does not allow you to access memory outside of the virtual space of your application. Thus the processes act as if they are unaware of each other's data. Even if you send a pointer to the other application, it will not be able to access the data. There are a few other options for interapplication communication.
    1. When you are calling CreateProcess() you can pass the new process some command line arguments. If the data you want to send can be serialized, then you can pass it to the other application at start using this command.
    2. You can pass the data using WM_COPYDATA which allows you to set up a special structure and send it to the other application. This is similar to what you wanted to do with the thread safe variables, except that this data will be read only and must be sent to the other process using something like SendMessage(). This gets quite a bit more complicated.
    3. You can set up a client server architecture and have all of the data management handled by the server process.
    From what you have said about your application so far, it may be simpler to just create a single process with two threads. If the applications are dependent on each other, then they likely need to be part of the same process.
    National Instruments
    Product Support Engineer

  • Can use the same thread safe variable in the different processes?

    Hello,
    Can  use the same thread safe variable in the different processes?  my application has a log file used to record some event, the log file will be accessed by the different process, is there any synchronous method to access the log file with CVI ?
    David

    Limiting concurrent access to shared resources can be better obtained by using locks: once created, the lock can be get by one requester at a time by calling CmtGetLock, the other being blocked in the same call until the lock is free. If you do not want to lock a process you can use CmtTryToGtLock instead.
    Don't forget to discard locks when you have finished using them or at program end.
    Alternatively you can PostDeferredCall a unique function (executed in the main thread) to write the log passing the apprpriate data to it.
    Proud to use LW/CVI from 3.1 on.
    My contributions to the Developer Zone Community
    If I have helped you, why not giving me a kudos?

  • Thread safe Timed Set

    Hello,
    I'm trying to create a thread safe set that also contains a time when it was updated last. It's a cache of a table from the db. I am using CopyOnWriteArraySet as the set is going to be modified rarely, items from set are never modified or removed individually.
    There are couple of questions, is the an existing collection that I can use to achieve the same in JDK 6 (not external libraries)? Is there a better choice over CopyOnWriteArraySet? I tried searching but couldn't find anything.
    If not, would the following implementation suffice my requirements?
    Any suggestions greatly appreciated.
    Thanks in advance,
    -t
    public class CacheSet<T> extends CopyOnWriteArraySet<T> {
    private static final long serialVersionUID = 1L;
    private long lastSyncTime = 0;
    * @param lastSyncTime
    *          the lastSyncTime to set
    public synchronized void setLastSyncTime(long lastSyncTime) {
    this.lastSyncTime = lastSyncTime;
    * @return the lastSyncTime
    public synchronized long getLastSyncTime() {
    return lastSyncTime;
    }

    if you are caching the contents of a table, i assume you are only ever replacing the set. i would suggest something like this:
    public class TableData<T>
      private final Set<T> _tableData;
      private final long _timestamp;
      public TableData(Set<T> data, long timestamp) {
        _tableData = Collections.unmodifiableSet(data);
        _timestamp = timestamp;
      // normal accessors here
    public class TableCache<T>
      private volatile TableData<T> _curTable;
      public void update(TableData<T> newTable)
        _curTable = newTable;
      public TableData<T> get()
        return _curTable;
    }the basic idea is that the TableData class is immutable (e.g. when you update the cache, you create a new set and new TableData instance), so you don't need to worry about concurrency issues (you can pass it a normal HashSet or whatever). thread visibility issues are resolved by using volatile on the TableCache class.
    Edited by: jtahlborn on Apr 17, 2010 10:47 AM

  • Using IPortalComponentProfile: Thread safe variables?

    Hi guys!
    I’m trying to understand (deeply) the framework used by the EP and I found something that disturb me like crazy… the use of the IPortalComponentProfile.
    I just don’t get it The profile suppose to hold variables for your iView instance right? Now, if you are trying to have thread safe variables in your iView  (which is desirable) why you have to used the “application” scope (in a JSP page) to retrieve those variables??? As you know, the application object in a JSP page refers to the ServletContext: All those variables are visible to the entire application which is completely the opposite to the thread safe concept… Am I wrong? Did I miss something?
    If you guys have the clue about this please let me know…
    Thanks in advance!
    Bye.
    Al

    Here's the answer taking from the Portal docs:
    "Except the scope option APPLICATION all the other scope options follow the JSP specifications from Sun Microsystems. <b>The option APPLICATION had to be modified to meet the requirements for a portal.</b> The standard recommendation of APPLICATION would allow access to a the bean through out the whole portal (it would be located in the "Web Application" shell if you look at the following overview chart). In the portal the sphere for APPLICATION is defined as the portal component. This gives the portal component control over the bean but the bean cannot be accessed by other users or other applications of the same user."
    Al.

  • If can think the thread safe variable as another lock method

    Hello,
    Assuming that there are two threads, using a thread safe variable as a signal condition. When the 1st thread calling the GetPointerToVarName() to do something, at the "same time", the 2nd thread need to call  GetPointerToVarName() to modify something, I'd like to know if the 2nd thread can continue the work until the 1st thread call the ReleasePointerToVarName()?
    David

    Thread safe variables can only be accessed by one thread at a time, so while the first one is holding the pointer, the second one waits until the pointer is released.
    This is more rigid than using thread locks, in that a thread could call CmtTryToGetLock remaining free to run even if the lock cannot be acquired (supposing running without the locked object makes sense).
    But it is not clear to me from your question whether you actually want thread safe variable functions to lock or are afraid they will do so...
    Proud to use LW/CVI from 3.1 on.
    My contributions to the Developer Zone Community
    If I have helped you, why not giving me a kudos?

  • SSRS - Is there a multi thread safe way of displaying information from a DataSet in a Report Header?

     In order to dynamically display data in the Report Header based in the current record of the Dataset, we started using Shared Variables, we initially used ReportItems!SomeTextbox.Value, but we noticed that when SomeTextbox was not rendered in the body
    (usually because a comment section grow to occupy most of the page if not more than one page), then the ReportItem printed a blank/null value.
    So, a method was defined in the Code section of the report that would set the value to the shared variable:
    public shared Params as String
    public shared Function SetValues(Param as String ) as String
    Params = Param
    Return Params 
    End Function
    Which would be called in the detail section of the tablix, then in the header a textbox would hold the following expression:
    =Code.Params
    This worked beautifully since, it now didn't mattered that the body section didn't had the SetValues call, the variable persited and the Header displayed the correct value. Our problem now is that when the report is being called in different threads with
    different data, the variable being shared/static gets modified by all the reports being run at the same time. 
    So far I've tried several things:
    - The variables need to be shared, otherwise the value set in the Body can't be seen by the header.
    - Using Hashtables behaves exactly like the ReportItem option.
    - Using a C# DLL with non static variables to take care of this, didn't work because apparently when the DLL is being called by the Body generates a different instance of the DLL than when it's called from the header.
    So is there a way to deal with this issue in a multi thread safe way?
    Thanks in advance!
     

    Hi Angel,
    Per my understanding that you want to dynamic display the group data in the report header, you have set page break based on the group, so when click to the next page, the report hearder will change according to the value in the group, when you are using
    the shared variables you got the multiple thread safe problem, right?
    I have tested on my local environment and can reproduce the issue, according to the multiple safe problem the better way is to use the harshtable behaves in the custom code,  you have mentioned that you have tryied touse the harshtable but finally got
    the same result as using the ReportItem!TextBox.Value, the problem can be cuased by the logic of the code that not works fine.
    Please reference to the custom code below which works fine and can get all the expect value display on every page:
    Shared ht As System.Collections.Hashtable = New System.Collections.Hashtable
    Public Function SetGroupHeader( ByVal group As Object _
    ,ByRef groupName As String _
    ,ByRef userID As String) As String
    Dim key As String = groupName & userID
    If Not group Is Nothing Then
    Dim g As String = CType(group, String)
    If Not (ht.ContainsKey(key)) Then
    ' must be the first pass so set the current group to group
    ht.Add(key, g)
    Else
    If Not (ht(key).Equals(g)) Then
    ht(key) = g
    End If
    End If
    End If
    Return ht(key)
    End Function
    Using this exprssion in the textbox of the reportheader:
    =Code.SetGroupHeader(ReportItems!Language.Value,"GroupName", User!UserID)
    Links belowe about the hashtable and the mutiple threads safe problem for your reference:
    http://stackoverflow.com/questions/2067537/ssrs-code-shared-variables-and-simultaneous-report-execution
    http://sqlserverbiblog.wordpress.com/2011/10/10/using-custom-code-functions-in-reporting-services-reports/
    If you still have any problem, please feel free to ask.
    Regards
    Vicky Liu

  • Thread safe doubt

    Hi every1
    My question:
    Multiple threads enter the method att()...i want to count how much time does attacher.attach() method takes for every thread that comes in...i think the code below works... but if i declared the timeTakenForAttach as global variable..someone told me its not thread safe...can some1 please explain me the meaning of all this OR can i declare timeTakenForAttach as global and it won't be a problem..
    class A{
      long totalAttachSetupMillis=0L;
      public void att() {
          long start = System.currentTimeMillis();
                   attacher.attach();
          long timeTakenForAttach = System.currentTimeMillis() - start;
           recordAttachSuccess (timeTakenForAttach);
       public synchronized void recordAttachSuccess(long timeForAttach){
                totalAttachSetupMillis += timeForAttach;
    }Thankyou..

    javanewbie83 wrote:
    I have to sychronize record sucess as different threads would enter att() and enter record success method and simultaneously update, so i will end up getting a wrong value.Let me give you a more detailed explanation of why NOT having it synchronized would not work.
    First of all, let's take a look at the statement of concern:
    totalAttachSetupMillis += timeForAttach;For the purposes of synchronization, however, we need to look at it like this:
    int temp = totalAttachSetupMillis + timeForAttach; //call this LINE A
    totalAttachSetupMillis = temp; //call this LINE BNow, lets say we had threads named 1 and 2. If you didn't sychronize the method, you could possibly have this execution flow:
    //initial values: totalAttachSetupMillis = 0, timeForAttack(1) = 20, timeForAttack(2) = 30.  Total should be 50
    1A //temp(1) = 0 + 20 = 20
    2A //temp(2) = 0 + 30 = 30 (remember totalAttachSetupMillis isn't set until B)
    2B //totalAttachSetupMillis = temp(2) = 30
    1B //totalAttachSetupMillis = temp(1) = 20 (instead of 50)In other words, total disaster could possibly ensue. Which is why you wanted to synchronize it. Ed's explanation of your other question was right on the money, though.

  • ODBC SQLGetData not thread-safe when retrieving lob

    Hi MaxDB developpers,
    we are in the process of migrating our solution from SapDb 7.4.03.32 to MaxDb 7.6.03.7. We use the ODBC driver on windows, from multi-threaded applications.
    We encountered bugs in the ODBC driver 7.4.03.32 and made our own fixes since we had the sources. I checked if these problems were fixed in 7.6.03.7 and they are allmost addressed, but one:
    when two threads use two different stmt from the same dbc and call simultaneously SQLGetData to retrieve a LONG column, a global variable not protected by a critical section is changed and the application crashes. The variable in cause is dbc_block_ptr->esqblk.sqlca.sqlrap->rasqlldp which is set by pa30bpcruntime and reset by pa30apcruntime during the call to apegetl. Calls to apegetl are protected by PA09ENTERASYNCFUNCTION except in SQLGetData, when it calls pa60MoveLongPos or pa60MoveLong.
    Since MaxDB is a critical feature of our application, we would like to know when this bug can be fixed by SAP. Or maybe could we get access to the sources of sqlod32w.dll 7.6.03.7 to fix it ourselves ?
    Thanks,
    Guillaume

    Hello Guillaume
    Regarding the threaded access to SQLGetData. Of course, it is possible to manage the syncronization as you proposed. However, I'm still not sure, whether this really solves general problems.
    The point is, that the MaxDB-ODBC driver is thread safe for concurrent connections, but not for concurrent statement processing within a single connection. Therefore I would like to ask you how your application accesses data via SQLGetData (due to connections and threads), and what amount of data is usually transfered.
    Regards  Thomas

  • Trying to understand "thread-safe" w/ swing components

    The other day there was a big hullabaloo about some code I posted because I was calling JLabel.setText from a thread that wasn't the ui thread. On the other hand, this thread was the only thread making changes to the JLabel. My understanding is that in any kind of multi-threaded system, if you just have 1 writer / changer, then no matter how many readers there are, this is thread-safe. So why what I was doing not thread safe?
    Second question - JLabel.setText() is essentially setting data in the model for JLabel, which then gets picked up and displayed the next time the GUI thread paints it. So if it's not safe to update a JLabel's model, I assume its never safe to update any data that also is being displayed visually. So for instance, if I was showing some database table data in a JTable, I should do the update in the UI thread - probably not. But what is the distinction?
    Third question - what swing components and what operations need to be run on the UI thread to call your program "thread-safe". Validate? setSize()? setLocation()? add? remove? Is there anything that can be called on swing components from a non-ui thread?
    Edited by: tjacobs01 on Nov 2, 2008 8:29 PM

    tjacobs01 wrote:
    My understanding is that in any kind of multi-threaded system, if you just have 1 writer / changer, then no matter how many readers there are, this is thread-safe. So why what I was doing not thread safe?This is not true. As I mentioned in that hullabaloo thread, the Java Memory Model allows threads to cache values of variables they use. This means that values written by one thread are not guaranteed to ever be visible to other threads, unless you use proper synchronization.
    Take the following example:
    import java.util.concurrent.TimeUnit;
    public class ThreadExample {
        static class Foo {
            private String value = "A";
            public String getValue() {
                return value;
            public void setValue(String value) {
                this.value = value;
        public static void main(String[] args) {
            final Foo foo = new Foo();
            Thread writer = new Thread() {
                @Override
                public void run() {
                    try {
                        TimeUnit.SECONDS.sleep(1);
                        foo.setValue("B");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
            Thread reader = new Thread() {
                @Override
                public void run() {
                    try {
                        TimeUnit.MINUTES.sleep(1);
                        System.out.println(foo.getValue());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
            writer.start();
            reader.start();
    }Here two different threads both access the same Foo instance, which is initialized with a value of "A". One thread, the writer, sleeps one second, and then sets foo's value to "B". The other thread, the reader, sleeps one minute (to avoid race conditions) and then prints foo's value to System.out. It may seem obvious that the reader thread will read the value "B", but this is in fact not guaranteed to be true. The reader thread may never see the value that was written by the writer thread, so it may very well read the old value "A".
    (If you run the code you will probably see "B" printed out, but again, this is not guaranteed behavior.)
    A simple way to fix this is to synchronize access to the mutable state that the two threads share. For example, change the class Foo to
        static class Foo {
            private String value = "A";
            public synchronized String getValue() {
                return value;
            public synchronized void setValue(String value) {
                this.value = value;
        }It's for this same reason that you often see the use of a volatile boolean as a control flag for stopping threads, rather than a plain old boolean. The use of volatile guarantees that the thread you want to stop actually sees the new value of the flag once it has been set by another thread.
    Here is an article that touches some of this stuff:
    [http://www.ibm.com/developerworks/java/library/j-jtp02244.html]
    I also highly recommend the book "Java Concurrency in Practice" (one of the authors of which, David Holmes, sometime hangs out on the Concurrency forum here, I believe).
    Edited by: Torgil on Nov 2, 2008 9:01 PM

  • Thread safe bean

    My business logic bean is being accessed via jsp's
    It looks something like this
    public class MyBean
    private int myInt;
    private String MySting;
    * Bean sets and gets
    public void setMyInt(int i)
    myInt = i;
    public void setMyString (String s)
    myString = s;
    public int getMyInt()
    return myInt;
    public String getMyString()
    return myString;
    * Public wrapper for private business logic
    public void doSomethingWrapper()
    myString = doSomething(getMyInt())
    * Private business logic
    private String doSomething(int i)
    // business Logic
    return a_string;
    Now, I've been told that this is not thread safe and that will not work. My big concern is
    with making the Bean properties thread safe, anyone way any suggestions? Thanks in advance.

    Based on your requirement, i see a necessicity for session scoping the bean.
    And yes in servlet/jsp multiple thread can act on single instance of a bean.
    So what you do is add synchronized keyword for the getter and setter method. For example if have modify your example given above, it would look something like this
    public class MyBean
    private int myInt;
    private String MySting;
    * Bean sets and gets
    public synchronized void setMyInt(int i)
       myInt = i;
    public synchronized void setMyString (String s)
       myString = s;
    public synchronized int getMyInt()
       return myInt;
    public synchronized String getMyString()
       return myString;
    * Public wrapper for private business logic
    * You dont necessarily have to synchronze this method because
    * getMyInt() is anyway synchronized.
    public void doSomethingWrapper()
       myString = doSomething(getMyInt())
    * Private business logic
    * If you dont access any properties(member variables) dont synchronize, if you do then yes
    private String doSomething(int i)
       // business Logic
       return a_string;
    }By adding synchronized keyword the java virtual machine ensures method level serial execution, so no corruption problem.
    But you require more than method level synchronization, then you need some other mechanism like semaphore and just.
    In most of the case, former would be just enough but if your case is not so then let me know, I can suggest other mechanism which suit your needs

Maybe you are looking for

  • Itunes no longer works on ipad on version 6 software

    My I tunes 10.6.1 no longer works with my upgraded software ipad 2 on version 6 stating my mac needs a higher operating system (currently on 10.5.8) to then upgrade I tunes 10.7. I can no longer use my ipad with itunes simply because I have an older

  • Can I move files frm 9.2 to Tiger with 1-3 periods in their filenames?

    I need to move big collection of images & design files that have 1-3 periods in their file names. Can I move them from my G4 (9.2) to my Intel iMac (10.4.9) without creating problems? I mostly use Quark, Adobe/Photoshop CS3, Acrobat & Preview (but no

  • Erratic behaviour with Tiger 10.4.6

    I have installed Tiger on my B&W G3, upgraded with a ZIF G4/500 OWC upgrade. I did not upgrade the previous installation of Panther, but made a fresh install of Tiger on the SCSI drive connected to my Atto card. I am experiencing erratic behaviour fr

  • Fetch data from prod servers

    Hi all, can anyone help me in developing package with below requirement: requirement  Excel sheet contains all the  emp_ids ..these emp_ids should be searched in Emp DB and return the output to an new excel sheet. Excel sheet Emp _ID 111   222 33  --

  • How do I get out of "full screen mode" on my tablet?

    I don't know how I got into full screen mode first of all and I can not figure out how to get out of full screen mode. I have a tablet, my toolbar with the menu symbol is missing at the top and the bar at the bottom is missing. I don't have any keys