Невозможно контролировать количество виртуальных потоковJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Невозможно контролировать количество виртуальных потоков

Сообщение Anonymous »

У меня есть следующий Java-код. Здесь я пытаюсь контролировать количество виртуальных потоков, изученных и вдохновленных этим потоком SO. Но все же я вижу отдельное и неконтролируемое количество идентификаторов потоков для каждой файловой операции. Чего мне здесь не хватает?
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class VirtualThreadDirectoryCopy4 {

public static void main(String[] args) throws Exception {

Path source = Path.of("C:\\source");
Path target = Path.of("C:\\source2");

int maxVirtualThreads = 2; // set your VT limit here

copyDirectory(source, target, maxVirtualThreads);
}

public static void copyDirectory(Path source, Path target, int maxThreads) throws Exception {

// Create a fixed-size virtual-thread executor
ExecutorService executor = Executors.newThreadPerTaskExecutor(
Thread.ofVirtual().factory()
);

// Use a semaphore to limit concurrency
final Semaphore semaphore = new Semaphore(maxThreads);

try (executor) {
Files.walk(source).forEach(path -> {
Path relative = source.relativize(path);
Path dest = target.resolve(relative);

if (Files.isDirectory(path)) {
try {
Files.createDirectories(dest);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
} else {
executor.submit(() -> {
try {
semaphore.acquire();
copyFileWithThreadInfo(path, dest);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release();
}
});
}
});
}
}

private static void copyFileWithThreadInfo(Path src, Path dest) {
long start = System.nanoTime();

Thread t = Thread.currentThread();
String threadName = t.getName();
long threadId = t.threadId();

try {
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);
long end = System.nanoTime();

long millis = (end - start) / 1_000_000;

System.out.printf(
"Thread %s (ID %d) copied %s → %s in %d ms%n",
threadName, threadId, src, dest, millis
);

} catch (IOException e) {
System.err.printf(
"Thread %s (ID %d) failed to copy %s: %s%n",
threadName, threadId, src, e.getMessage()
);
}
}
}

Обновление:
На основе предложений и комментариев DuncG я придумал следующее:
Semaphore semaphore = new Semaphore(maxThreads);

try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {

for (Path file : files) {
try {
semaphore.acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}

executor.submit(() -> {
try {
copyFileTask(file, source, target);
} finally {
semaphore.release();
}
});
}
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... al-threads
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»