java中的多线程

发布于 2024-11-02 01:28:13 字数 1466 浏览 3 评论 0原文

我希望“runnable”以 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();
}

}

I want "runnable" to run at 5tps. This is not executing paralelly.

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();
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

葬シ愛 2024-11-09 01:28:13

考虑一下:

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

我希望您应该清楚,您将在短短几分钟内耗尽池中的线程几秒钟,你就会失去并行性。您需要通过降低频率或减少睡眠来更好地平衡这一点。增加池大小不会有帮助,您仍然会耗尽线程。

Consider this:

  • Your tasks are sleeping for 7 seconds during their execution
  • You are scheduling a new task every 200ms
  • You only have 50 threads in your executor

It should be clear, I hope, that you'll run out of pooled threads in just a few seconds, and you'll lose your parallelism. You need to balance this better, either by reducing the rate or reducing the sleep. Increasing the pool size won't help, you'll still run out of threads.

别想她 2024-11-09 01:28:13

scheduleAtFixedRate 仅生成单个线程,但以固定速率执行提供的可运行对象。

  • 该操作运行的时间少于给定的时间段:在这种情况下,它会在指定的时间段内重新生成。
  • 该操作运行时间更长(您的情况):该操作立即再次开始。

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

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

但在可运行的 run 方法内添加下一个调用,

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

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

scheduleAtFixedRate does only spawn a single thread but executes the runnable provided with a fixed rate.

  • The action runs in less amount of time than the given period: in this case it is respawned with exactly the specified period.
  • The action runs longer (your case): the action is started again immediately.

If you want to have the desired behaviour you may use the following pattern: Just execute the runnable once:

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

but inside the runnable's run method add the next invokation by

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

Nevertheless consider the arithmetic as described in the answer by skaffman.

紫南 2024-11-09 01:28:13

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

我验证了如果您更改 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();

Update: Howard is right, my first example was wrong.

I verified this works if you change your active() method:

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文