有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程这是一种很好的方法,可以对Java类的多个函数进行线程化和同步吗?

我有一个类Prefs,它有多种方法。我需要使用线程和同步重写它

我在看这个变体:http://tutorials.jenkov.com/java-concurrency/synchronized.html

因此,目前:

class T_readConfigFile extends Thread {
  protected Prefs p = null;
  public T_readConfigFile(Prefs p) {
    this.p =p;
  }

  public void run() {
    p.readConfigFile();
  }
} 

 public synchronized void readConfigFile() { ...

但不知何故,为我想要线程化的每个方法创建N个相同的类看起来不是一个好主意。我想这是整个班级的问题。p=p;加载到内存中-如果我从那里只使用一个方法,我真的需要它吗

所以:这很有效,但我不喜欢,有更好的方法吗


共 (2) 个答案

  1. # 1 楼答案

    synchronized方法锁定该方法的类对象,以便一次只能有一个线程执行该方法。例如,在不希望多个线程同时读取或写入同一文件或流的情况下,这非常有用

    如果需要每个线程读取自己的单独配置文件,则可能不需要同步readConfigFile()方法。另一方面,如果每个线程都读取相同的配置文件,则需要同步它

    但是,如果所有线程都在读取同一个配置文件,那么可能只有一个线程(或者可能是主父线程)读取该文件一次,然后将结果解析的配置值传递给每个线程。这节省了大量的I/O

  2. # 2 楼答案

    假设您想在后台线程中调用某个方法foo()。你已经找到了最基本的方法。以下是您所做工作的一个更好的变体:

    new Thread(new Runnable() {
        @Override
        public void run() {
            foo();
        }
    }).start();
    

    好的,我写了六行Java代码来调用一个函数。是的,有点冗长。欢迎使用Java(或者至少欢迎使用Java7。如果可以用Java8更简洁地完成,我还没有学会如何做。)

    不过,这种方法存在一些比冗长更糟糕的问题:

    1)每次要调用后台方法时,都会创建并销毁一个新线程。创建和销毁线程的成本相对较高

    2)如果后台任务的执行时间与您调用它们的频率相关,那么您无法控制同时运行的任务数量。在繁忙的应用程序中,它可能会不断增长,直到出现OutOfMemoryError

    更好的方法是使用线程池:

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    ...
    final int NUM_THREADS = ...;
    final ExecutorService executorService = Executors.newFixedThreadPool(NUM_THREADS);
    ...
    executorService.submit(new Runnable() {
        @Override
        public void run() {
            foo();
        }
    });
    

    每次向线程池提交新任务时,它都会唤醒一个已经存在的线程,该线程将执行该任务,然后返回睡眠状态。除非池启动,否则不会创建或销毁线程

    此外,如果在提交新任务时所有线程都很忙,则该任务将添加到队列中,稍后当工作线程可用时将执行该任务

    这只是一个简单的例子:java。util。concurrent package为您提供了更多的选项,包括限制队列大小的能力、根据需求生成增长或收缩的线程池的能力,也许最重要的是,等待任务完成的能力,以及从完成的任务中获取返回值的方法

    看看吧http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-frame.html