简单的Java回调不起作用

时间:2018-04-05 12:27:29

标签: java interface callback

interface CallableInterface
{
    void callBackMethod();
}

class Worker
{   
    public static ArrayList<String> names = new ArrayList<String>();
    static Timer t = new Timer();

    public void addToList(String newAdd, CallableInterface callback)
    {   
        names.add("BMW");
        names.add("DODGE");

        t.schedule(new TimerTask() {
            @Override
            public void run() {     
                names.add(newAdd);
            }
        }, 5000);

       callback.callBackMethod();
    }

    public void printList(){
        System.out.println(Worker.names);
    }
}


class Boss implements CallableInterface
{   
    Worker w1 = new Worker();

    public Boss(String carName)
    {   
        w1.addToList(carName, this);
    }
    public void callBackMethod()
    {
        w1.printList();
    }
}


public class IntroCallbacks
{ 
    public static void main(String[] args)
    {
        Boss b = new Boss("Mercedes");   
    }
}

我正在使用计时器模拟网络延迟。想法是等待计时器完成(在这种情况下为5秒),然后打印arrayList。无论我对代码做什么,我总是只能获得[BMW,DODGE]。

它应该是[BMW,DODGE,MERCEDES]。

我缺少什么?

3 个答案:

答案 0 :(得分:5)

调度计时器后,

Worker::addToList立即调用Boss::callBackMethod。这将打印列表,该列表目前只有2个元素。 〜4.99秒后,最后一个元素被添加到列表中,但它已被打印。

如果您只想在添加第3个元素后打印列表,请将回调调用移至添加该元素之后:

public void addToList(String newAdd, CallableInterface callback)
{   
    names.add("BMW");
    names.add("DODGE");

    t.schedule(new TimerTask() {
        @Override
        public void run() {     
            names.add(newAdd);
            callback.callBackMethod();
        }
    }, 5000);
}

或使用某种同步机制,如CountDownLatch

答案 1 :(得分:2)

在添加名称后,我会使用if (t1.equals(t2)) { t1 = t2; } 来链接打印。您可以使用延迟CompletableFuture代替Executor来引入5秒延迟。

Timer

最后必须等到将来import static java.util.concurrent.TimeUnit.SECONDS; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; class Worker { private List<String> names = new ArrayList<String>(); public CompletableFuture<Void> addToList(String name, Runnable callback) { names.add("BMW"); names.add("DODGE"); Executor in5seconds = CompletableFuture.delayedExecutor(5, SECONDS); return CompletableFuture.runAsync(() -> names.add(name), in5seconds) .thenRun(callback::run); } public void printList() { System.out.println(names); } } class Boss implements Runnable { private Worker worker = new Worker(); private CompletableFuture<Void> future; public Boss(String carName) { future = worker.addToList(carName, this); } public void run() { worker.printList(); } public CompletableFuture<Void> getFuture() { return future; } } public class IntroCallbacks { public static void main(String[] args) { Boss boss = new Boss("Mercedes"); boss.getFuture().join(); } } isDone(),否则程序将结束,并且后台守护程序线程将在任何有趣的东西(包括输出)之前终止发生了。

答案 2 :(得分:1)

此代码将解决您的问题..:)

    import java.util.ArrayList;
    import java.util.Timer;
    import java.util.TimerTask;

    interface CallableInterface
    {
        void callBackMethod();
    }

    class Worker
    {   
        public static ArrayList<String> names = new ArrayList<String>();
        static Timer t = new Timer();

        public void addToList(String newAdd, CallableInterface callback)
        {   
            names.add("BMW");
            names.add("DODGE");

            t.schedule(new TimerTask() {
                @Override
                public void run() {     
                    names.add(newAdd);
                    callback.callBackMethod();
                }
            }, 5000);


        }

        public void printList(){
            System.out.println(Worker.names);
        }
    }


    class Boss implements CallableInterface
    {   
        Worker w1 = new Worker();

        public Boss(String carName)
        {   
            w1.addToList(carName, this);
        }
        public void callBackMethod()
        {
            w1.printList();
        }
    }

    public class Main {

        public static void main(String[] args) {
            Boss b = new Boss("Mercedes");   

        }

    }