0

I have a program that starts a thread. In the constructor I pass a volatile boolean, but when the variable is changed in the main thread, this change isn't reflected in the thread.

I declare the following in the main class.

private static volatile boolean sendbuff1;
private static volatile boolean sendbuff2;
private static volatile boolean closeSession;

And start the thread like this.

try{
    Thread uploader = new Thread(new appendObj(buffer1loc, buffer2loc, sendbuff1, sendbuff2, closeSession));
    uploader.start();
    Thread.sleep(5000);
    } catch (Exception e) {
        e.printStackTrace();
    }

Later in the main function, the sendbuff1 is set from false to true, but the sendbuff1 in the thread doesn't change. I was printing it out and it stayed false.

In the appendObj thread,

while(!closeSession) {

        if (sendbuff1) {
            //append
            System.out.println("sendbuff 1 changed");

            try {
            PrintWriter tobuff1 = new PrintWriter(new File(buffer1loc));
            try1.appendFile(buffer1loc);
            tobuff1.write("");
            tobuff1.close();
            sendbuff1 = false;
            } catch (Exception e) {
                System.out.println("error caught print writing send buff 2");
                e.printStackTrace();
            }
        }

        if (sendbuff2) {
            System.out.println("sendbuff 2 changed");
            try {
            PrintWriter tobuff2 = new PrintWriter(new File(buffer2loc));
            try1.appendFile(buffer2loc);
            tobuff2.write("");
            tobuff2.close();
            sendbuff2 = false;
            } catch (Exception e) {
                System.out.println("error caught print writing send buff 2");
                e.printStackTrace();
            }
        }



    }

No idea what I'm doing wrong

  • @SotiriosDelimanolis Does that question matter in case of primitive variables? I guess the problem is, that `appendObj` has his own variable with the value of `sendbuff1` and since it is the primitive type, only `true` or `false` will be stored, not a object reference. – Tom Jun 02 '15 at 15:20
  • @Tom There are multiple misconceptions here. First, `volatile` applies to the field, not to the referenced object or primitive value. Second, they are not accessing the fields, they are accessing a copy of the value that was stored in the field through some other field or local variable. – Sotirios Delimanolis Jun 02 '15 at 15:21
  • @SotiriosDelimanolis Yes that is right and I now understand that the duplicate is in fact correct. I "ignored" the question about "pass by reference", because it is a primitive type, so it is already clear, that the value will be passed, but OP might not know that. – Tom Jun 02 '15 at 15:24
  • volatile variables is a very poor way to pass tasks between threads. I suggest you use an ExecutorService and pass Runnable to write data to files. – Peter Lawrey Jun 02 '15 at 15:25
  • Thanks. So then how do I have a boolean in the threads that is updated when a value in the main thread is updated? I have done something similar with a BlockingQueue and two threads seems to be able to change and notice changes in that variable. Not sure how to do it with booleans. – user3774221 Jun 02 '15 at 15:26
  • @user3774221 the problem you have is there is no way of knowing if a) the boolean is set to true more than once e.g. before you set it to false, b) no way to know if the value is set to true immediately after it is set to false. You are trying to use a boolean in a way which is not suitable to your purposes. – Peter Lawrey Jun 02 '15 at 15:31
  • @SotiriosDelimanolis how does the marked duplicate relate to the question as it is currently. Is this still a duplicate? – Peter Lawrey Jun 02 '15 at 15:32
  • @PeterLawrey I think so. I think they are wondering why the values passed in the `appendObj` constructor aren't reflecting the changes in the `private static final volatile` fields declared in some other class. What am I missing? – Sotirios Delimanolis Jun 02 '15 at 15:33
  • @SotiriosDelimanolis thank you for clarifying that, I think you are right. I didn't think someone would create a global variable and use a local copy. Even if they fixed this, it would still be a broken pattern to use. – Peter Lawrey Jun 02 '15 at 15:38
  • @user3774221 Consider looking into other concurrency primitives and inter-thread communication mechanisms. Blocking Queues are one option. Semaphores, locks, etc. are others. – Sotirios Delimanolis Jun 02 '15 at 15:41

0 Answers0