0

Let's assume I have a lot of objects:

public class Main {
    public static DB d1 = new DB(1);
    public static DB d2 = new DB(2);
    public static DB d3 = new DB(3);
    public static DB d4 = new DB(4);

and I want to modify them.

    public static void main(String[] args) {
        d1.modifyObject();
        d2.modifyObject();
        d3.modifyObject();
        d4.modifyObject();
    }
}

and I want them to be modified simultaneously, for it takes some time. Looks like I need multithreading.

This is my DB class:

import java.awt.EventQueue;
import java.util.Date;
import java.util.Random;

public class DB {
    private int id = 0;
    private long field = 0;

    public void DB(int id) {
        this.id = id;
    }

    // The contents of this method are not very important.
    private void modifyField() {
        // [some database interactions which take some seconds to execute]
        // for simplicity, emulated with sleep:
        long newValue = 0;
        try {
            newValue = (this.id + new Date().getTime()) % 42;
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.field = newValue;
    }

    public void modifyObject() {
        Runnable r = new Runnable(){ @Override public void run() {
            this.modifyField(); // THIS DOES NOT WORK OF COURSE, I can't access the objects content from a thread
        }};
        EventQueue.invokeLater(r);
    }
}

I want the contents of Main.d1, Main.d2, Main.d3, Main.d4 and so on to be changed without delaying the main thread. I used to do it by accessing Main.d1 within DB itself. This obviously only works if I have just one object. Now, since I have to handle multiple objects, I can't access Main's objects statically any more.

My question is simple but I fear there is no easy answer to it: What options do I have to put this.modifyField(); into its own thread?

How can I make an object modify itself in a thread?

2
  • 2
    Use an Executor or ExecutorService Commented Mar 19, 2015 at 23:29
  • 1
    THIS DOES NOT WORK OF COURSE, I can't access the objects content from a thread You need to use DB.this Commented Mar 19, 2015 at 23:34

2 Answers 2

1

I think you simply have the wrong this.

Here:

    Runnable r = new Runnable(){ @Override public void run() {
        this.modifyField(); // THIS DOES NOT WORK OF COURSE, I can't access the objects content from a thread
    }};

this refers to the new Runnable. You can access the enclosing DB object thusly:

    Runnable r = new Runnable(){ @Override public void run() {
        DB.this.modifyField();
    }};

Also, if you are using Java 8, you can write that whole bit more succinctly using a method reference:

Runnable r = this::modifyField;
Sign up to request clarification or add additional context in comments.

Comments

1

Use an ExecutorServce:

public void foo() throws InterruptedException {
    final ExecutorService executorService = newFixedThreadPool(4); //find what works best for you, setting the number of threads as the number of tasks will not be the best solution in all cases

    final Future<?> runD1Modify = executorService.submit(getModifyObjectRunnable(d1));
    final Future<?> runD2Modify = executorService.submit(getModifyObjectRunnable(d2));
    final Future<?> runD3Modify = executorService.submit(getModifyObjectRunnable(d3));
    final Future<?> runD4Modify = executorService.submit(getModifyObjectRunnable(d4));

    // or in java8

    final Future<?> runD1Modify = executorService.submit(() -> d1.modifyField());
    final Future<?> runD1Modify = executorService.submit(() -> d2.modifyField());
    final Future<?> runD1Modify = executorService.submit(() -> d3.modifyField());
    final Future<?> runD1Modify = executorService.submit(() -> d4.modifyField());
}

private Runnable getModifyObjectRunnable(final DB db) {
    return new Runnable() {
        @Override
        public void run() {
            db.modifyField();
        }
    };
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.