Làm thế nào để định cấu hình một nhóm chủ đề được tinh chỉnh cho tương lai?


80

Nhóm chủ đề của Scala cho tương lai lớn đến mức nào?

Ứng dụng Scala của tôi tạo ra hàng triệu future {}s và tôi tự hỏi liệu tôi có thể làm gì để tối ưu hóa chúng bằng cách định cấu hình nhóm luồng.

Cảm ơn bạn.


Slick 3.0 sử dụng kết nối riêng và threadpool vậy tại sao chúng ta cần cung cấp executioncontext ngầm để trơn khi nó quản lý hồ bơi thread riêng
Rahul Gulabani

1
@RahulGulabani, từ cuốn sách " The reason is that map, flatMap methods of Action allows you to call arbitrary code when joining the actions together. Slick cannot allow that code to be run on its own execution context, because it has no way to know if you are going to tie up Slicks threads for a long time.
Essential

Câu trả lời:


90

Bạn có thể chỉ định ExecutionContext của riêng mình mà tương lai của bạn sẽ chạy, thay vì nhập ExecutionContext ngầm toàn cầu.

import java.util.concurrent.Executors
import scala.concurrent._

implicit val ec = new ExecutionContext {
    val threadPool = Executors.newFixedThreadPool(1000)

    def execute(runnable: Runnable) {
        threadPool.submit(runnable)
    }

    def reportFailure(t: Throwable) {}
}

73
Câu trả lời tuyệt vời, bạn có thể giảm bớt một chút bản soạn sẵn bằng cách sử dụng các phương thức trợ giúp trên ExecutionContext cho phép bạn khởi tạo trực tiếp từ một Executor đã cho. Ví dụ: implicit val ec = ExecutionContext.fromExecutor (Executor.newFixedThreadPool (10))
sksamuel

1
Cho rằng tất cả điều này là tốt, nhưng có giới hạn thực sự trong chủ đề trên implicits.global không? Nếu vậy thì cấu hình này có giống như akka qua application.conf không?
Nick

6
@Nick yes, implicits.global chỉ là 1 luồng cho mỗi lõi CPU. Tối ưu cho các tác vụ ràng buộc cpu. Nhưng đối với IO chặn cổ điển (ví dụ: jdbc) thì đó là một thảm họa về hiệu suất.
Ben Hutchison

2
Tôi cần thêm lệnh gọi để tắt nhóm luồng sau khi sử dụng điều này hoặc chương trình không bao giờ kết thúc ... def shutdown () = threadPool.shutdown ()
justinhj

2
Tại sao nó tắt trong trường hợp "bình thường", nhưng không phải khi chúng ta đặt hàm ẩn cho một thứ khác?
hbogert

152

Câu trả lời này là từ monjack, một bình luận từ câu trả lời được chấp nhận. Tuy nhiên, người ta có thể bỏ lỡ câu trả lời tuyệt vời này vì vậy tôi đăng lại nó ở đây.

implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))

Nếu bạn chỉ cần thay đổi số lượng nhóm luồng, chỉ cần sử dụng trình thực thi toàn cục và chuyển các thuộc tính hệ thống sau.

-Dscala.concurrent.context.numThreads=8 -Dscala.concurrent.context.maxThreads=8

2
đây là một giải pháp thanh lịch
Bến Hutchison

Tôi đã thử cả hai điều này với giá trị là 5 và tôi vẫn thấy tối đa 8 luồng chạy đồng thời.
micseydel

3

cách tốt nhất để chỉ định threadpool trong tương lai scala:

implicit val ec = new ExecutionContext {
      val threadPool = Executors.newFixedThreadPool(conf.getInt("5"));
      override def reportFailure(cause: Throwable): Unit = {};
      override def execute(runnable: Runnable): Unit = threadPool.submit(runnable);
      def shutdown() = threadPool.shutdown();
    }

0
class ThreadPoolExecutionContext(val executionContext: ExecutionContext)

object ThreadPoolExecutionContext {

  val executionContextProvider: ThreadPoolExecutionContext = {
    try {
      val executionContextExecutor: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(25))
      new ThreadPoolExecutionContext(executionContextExecutor)
    } catch {
      case exception: Exception => {
        Log.error("Failed to create thread pool", exception)
        throw exception
      }
    }
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.