【问题标题】:multithreading in javajava中的多线程
【发布时间】:2011-08-07 05:51:05
【问题描述】:

我希望“可运行”以 5tps 运行。这不是并行执行的。

package tt;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

public class mySpawner {

public int tillDone = 0;
public int tillMax = 0;
public ArrayList arrayList;
private myWorker myworking;
private ScheduledExecutorService service = Executors.newScheduledThreadPool(50);

Runnable runnable = new Runnable() {

    @Override
    public void run() {
        try {
            System.out.println(System.nanoTime());
            Thread.sleep(7000);
        } catch (InterruptedException ex) {
            Logger.getLogger(mySpawner.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
};


public void activate() {
    try {
        service = Executors.newScheduledThreadPool(50);
        service.scheduleAtFixedRate(runnable, 0, 200, TimeUnit.MILLISECONDS);
    } catch (Exception e) {//Catch exception if any
        System.err.println("Error: " + e.getMessage());
    }

}

public void deactivate() {
    service.shutdown();
}

}

【问题讨论】:

  • 不是说它会解决问题,但你在代码中初始化了两次service
  • 问题是它仅每 7 秒打印一次纳米时间。它应该每 200 毫秒打印一次吗?

标签: java multithreading threadpool


【解决方案1】:

考虑一下:

  • 您的任务在执行期间休眠了 7 秒
  • 您每 200 毫秒安排一个新任务
  • 您的执行程序中只有 50 个线程

我希望很清楚,您将在几秒钟内用完池线程,并且您将失去并行性。您需要通过降低速率或减少睡眠来更好地平衡这一点。增加池大小无济于事,您仍然会用完线程。

【讨论】:

  • 我把 sleep 放在那里模拟一个运行 7 秒的任务。现在它没有并行运行,这是一个问题(它打印 nanotime 并在 7 秒后打印下一个 nanotime 我怀疑他们不会每 200 毫秒打印一次吗?)
  • @user5574348 - 注意@skaffman 实际所说的话......并做一些算术。
【解决方案2】:

更新:霍华德是对的,我的第一个例子是错误的。

如果您更改 active() 方法,我已验证此方法有效:

service = Executors.newScheduledThreadPool(50);
new Thread() {
    public void run() {
        long nextTime = System.currentTimeMillis();
        while (true) {
            service.submit(runnable);
            long waitTime = nextTime - System.currentTimeMillis();
            Thread.sleep(Math.max(0, waitTime));
            nextTime += 200;
        }
    }
}.start();

【讨论】:

  • 感谢白牙。这将运行@ 5 tps ryt?
  • 这是在做一些完全不同的事情。它启动 50 个线程,每个线程每 200 毫秒运行一次。因此,在 200 毫秒后,它将执行第一个,另外还有第二个。 400 毫秒后它将同时运行三个,依此类推。它只是没有显示出来,因为每一个都需要 7 秒,并且在动作结束之前线程没有重新生成。
  • @Howard:谢谢,我更新了一个更好的答案,我验证了它在很长一段时间内保持每秒 5 次。
【解决方案3】:

scheduleAtFixedRate 只生成一个线程,但会以固定速率执行 runnable。

  • 动作运行的时间少于给定的时间:在这种情况下,它会以指定的时间重生。
  • 动作运行时间更长(您的情况):动作立即重新开始。

如果您想获得所需的行为,您可以使用以下模式:只需执行一次可运行对象:

service.schedule(runnable, 0, TimeUnit.MILLISECONDS);

但在 runnable 的 run 方法中添加下一个调用

service.schedule(runnable, 200, TimeUnit.MILLISECONDS);

尽管如此,请考虑 skaffman 的答案中描述的算术。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2014-06-13
    相关资源
    最近更新 更多