Java—使对象在线程中修改自身

Java—使对象在线程中修改自身,java,multithreading,object,Java,Multithreading,Object,让我们假设我有很多对象: 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); 我想修改它们 public static void main(String[] args) { d1.modif

让我们假设我有很多对象:

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);
我想修改它们

    public static void main(String[] args) {
        d1.modifyObject();
        d2.modifyObject();
        d3.modifyObject();
        d4.modifyObject();
    }
}
我希望同时修改它们,因为这需要一些时间。看起来我需要多线程

这是我的
DB
课程:

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);
    }
}
我希望在不延迟主线程的情况下更改
Main.d1
Main.d2
Main.d3
Main.d4
等的内容。我过去常常通过在
DB
本身中访问
Main.d1
来实现这一点。这显然只在我只有一个对象的情况下有效。现在,由于我必须处理多个对象,我不能再静态地访问
Main
的对象了

我的问题很简单,但我担心没有简单的答案:我必须把
this.modifyField()放在什么选项上编码到自己的线程中


如何使对象在线程中修改自身?我认为您的
这个
是错误的

在这里:

指的是
新的可运行
。您可以通过以下方式访问封闭的
DB
对象:

    Runnable r = new Runnable(){ @Override public void run() {
        DB.this.modifyField();
    }};
另外,如果您使用的是Java 8,则可以使用方法引用更简洁地编写整个过程:

Runnable r = this::modifyField;
使用ExecutorService:

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();
        }
    };
}
public void foo()抛出InterruptedException{
final ExecutorService ExecutorService=newFixedThreadPool(4);//查找最适合您的解决方案,将线程数设置为任务数并不是所有情况下的最佳解决方案
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));
//或者用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());
}
私有可运行getModifyObjectRunnable(最终数据库){
返回新的Runnable(){
@凌驾
公开募捐{
db.modifyField();
}
};
}

使用
这当然不行,我无法从线程访问对象内容
您需要使用
DB。这
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();
        }
    };
}