1
package com.company;

import java.io.Console;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Main {

    static boolean isToastShewnLeft = false;

    public static void main(String[] args) {

        showToastLeft("first", "", "");
        showToastLeft("second", "", "");
        showToastLeft("third", "", "");
        showToastLeft("fourth", "", "");
        showToastLeft("fifth", "", "");
    }

    public static void showToastLeft(final String paramToastString1, final String paramToastString2, final String paramToastString3) {

        final long start = System.currentTimeMillis();

        ScheduledExecutorService worker1 = Executors.newSingleThreadScheduledExecutor();

        ScheduledExecutorService worker2 = Executors.newSingleThreadScheduledExecutor();

        if (isToastShewnLeft) {

            final Runnable r = new Runnable() {
                @SuppressWarnings("StatementWithEmptyBody")
                public void run() {
                    while (isToastShewnLeft) {

                    }

                    isToastShewnLeft = true;

                    //This line does not appear in console output
                    //I can set a breakpoint on this println and see that it does execute
                    System.out.println(paramToastString1);

                    ScheduledExecutorService worker3 = Executors.newSingleThreadScheduledExecutor();

                    final Runnable r2 = new Runnable() {
                        public void run() {
                            isToastShewnLeft = false;

                            System.out.println(System.currentTimeMillis() - start + " Set toast not shewn");
                        }
                    };

                    worker3.schedule(r2, 5, TimeUnit.SECONDS);

                }
            };

            worker1.schedule(r, 0, TimeUnit.SECONDS);

        } else {
            isToastShewnLeft = true;

            System.out.println(paramToastString1);

            final Runnable r2 = new Runnable() {
                public void run() {
                    isToastShewnLeft = false;
                    System.out.println(System.currentTimeMillis() - start + " Set toast not shewn");
                }
            };

            worker2.schedule(r2, 5, TimeUnit.SECONDS);

        }
    }
}
            /Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/bin/java -Didea.launcher.port=7543 "-Didea.launcher.bin.path=/Applications/IntelliJ IDEA 14 CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/lib/javafx-doclet.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/lib/tools.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/htmlconverter.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Users/ericsepich/IdeaProjects/untitled1/out/production/untitled1:/Applications/IntelliJ IDEA 14 CE.app/Contents/lib/idea_rt.jar" com.intellij.rt.execution.application.AppMain com.company.Main
            first
            5008 Set toast not shewn

My intent is to show the texts 5 seconds apart at each call to showToastLeft. Is it possible that there is a problem using println from the executors thread? I am using IntelliJ idea as my IDE.

I will be posting a screenshot showing the value of the boolean to be true in my debugger. enter image description here

Thank you for any responses....

Eae
  • 3,891
  • 12
  • 47
  • 86
  • So the only output you see is `first` and then `5008 Set toast not shewn`? – sparc_spread May 26 '15 at 12:22
  • Correct. Is it possible there is threading problem with println? – Eae May 26 '15 at 12:23
  • I made a copy paste example that can be pasted into IntelliJ. I'm currently in a Yosemite environment. I think the JDK version is posted. – Eae May 26 '15 at 12:25

2 Answers2

2

You are not letting the Java threading system a chance to share the CPU between your threads.

                while (isToastShewnLeft) {
                  // Add this.
                  Thread.sleep(10);
                }
OldCurmudgeon
  • 60,862
  • 15
  • 108
  • 197
  • The sleep in this location seems to be a critical addition. It doesn't work without the sleep in the while. – Eae May 26 '15 at 12:46
  • The ordering is something I have to work out if I can't figure it out I may have to post another question about that. Thank you very much these are very enlightening posts. – Eae May 26 '15 at 12:50
1

You have multiple threads reading and writing the isToastShewnLeft variable without any concurrency protection. Try enclosing all read/write operations on isToastShewnLeft in synchronized and see if this makes a difference. The issue here may be a thread-related visibility problem: the subtle situation where threads keep their own copies of variables and reorder operations for efficiency. Synchronization is one way of preventing this with any shared variables. Here is one good explanation of visibility, and here is another.

Besides synchronized, you could use a java.util.concurrent.AtomicBoolean, if let's say you were really concerned about performance (which I doubt given the 5 seconds intervals). It's a bit more subjective whether you could get away with just making isToastShewnLeft into a volatile variable, but I would shy away from that given that the state of isToastShewnLeft affects what is written to it.

Community
  • 1
  • 1
sparc_spread
  • 9,481
  • 7
  • 40
  • 54
  • Generally I think I understand what you are saying and I need to read up on those articles. Right now the part that I am thinking about is that now that toast are showing at the proper interval but they are not in succession. The order is changed. – Eae May 26 '15 at 12:48