Jak ustawic zeby Thready uzywaly 50% dosepnych procesorw/threadow?

0

Mam cos takiego i zaczyna to około 1000 threadow ale komputer nadal laguję nawet jak te thready maja mały priorytet.
chciałbym jakoś to limitować żeby polowe dostępnych threadow mogło używać albo żeby 50% procesora jakoś używało.

mam 20 wątków wiec jak by te thready mogły używać od 11 do 20 wątka to by było ok

4

Na przykład tylko połowa dostępnych core do wzięcia

        int MAGIC_COEFFICIENT = 2;

        int nThreads = Runtime.getRuntime().availableProcessors();
        nThreads = nThreads / MAGIC_COEFFICIENT;
        
        final ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
0
		int MAGIC_COEFFICIENT = 2;
		int nThreads = Runtime.getRuntime().availableProcessors();
		nThreads = nThreads / MAGIC_COEFFICIENT;
		final ExecutorService executorService = Executors.newFixedThreadPool(nThreads);

		
		for (Thread thread : threads)
		{
			thread.setPriority(Thread.MIN_PRIORITY);
			executorService.submit(thread);
			thread.start();
		}

czyli cos takiego?

3
        executorService.submit(() -> System.out.println("Hello");

0

@BraVolt: a ok dzieki! sprawdzilem ale cpu i tak do 100% podbilo hmm

moze byc tak ze mam i tak inne programy wlaczone na tych watkach wiec i tak pewnie by lagowalo.

nie ma moze limitu uzytku watka do 50%? i pozwolic mu chodzic na wszyskich?

edit: 50% na kazdym watku

0

Wywaliles to thread start?

0

ta mam tak:

	        public static final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() / 2);

		for (Thread thread : threads)
		{
			thread.setPriority(Thread.MIN_PRIORITY);
			executorService.submit(thread);
		}

		for (Thread thread : threads)
		{
			thread.join();
		}
0

tylko ja włączam 15 tych programów w tym samym momencie i może one inne watki sobie wybierają może

0

.submit zwraca Future i to raczej wzgledem tego powinienes sie synchronizowac a nie watki joinowac.

We no zerknij w dokumentacje zamiast czarowac :p

0

join checka az wszystkie watki skończą zgina, to nie jest problemem tylko to ze do 100% procesora uzywalo

ale w sumie nawet jak bym uzywal 50% cpu, to i tak nie bedzie dzialac bo to jest skrypt do gry a 10 klijentow wlaczam, wiec kazdy klijent by uzywal do 50% cpu

0

dzieki za odpowiedzi.

1
Andy x napisał(a):

join checka az wszystkie watki skończą zgina, to nie jest problemem tylko to ze do 100% procesora uzywalo

var task = executorService.submit(thread);
task.get();
3

Skoro możesz mieć 10 klientów po 20 wątków (tasków) każdy, to dlaczego nie możesz mieć jednego klienta który odpali 200 wątków (tasków) w jednej puli wątków z limitowanym rozmiarem tak, by nie zjadać więcej niż połowy rdzeni? Rozumiem że tak czy owak właściwą robotę wykonują te taski.

2

@Andy x: pamiętaj też żeby na koniec zrobić shutdown ExecutorService ;)

1

@Andy x:

Zależy co te taski robią, bo jak je tylko uruchamiasz z jakimś ograniczeniem, a one sobie "uruchamiają CyberPunka każdy jeden"? ;)

Puść sobie prosty przykład (klasycznie liczby Fibonacci) i obserwuj jak pod koniec zadań (blisko 50) zachowuje się obciążenie rdzeni.
Na koniec będą obciążone 3, potem 2 i jeden (najdłużej, liczący fibonacci(49)).
Po prostu, co wrzucisz, co zadasz, to jest robione.

package com.app;

import lombok.SneakyThrows;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;

public class Example {

    @SneakyThrows
    public static void main(String[] args) {

        int nThreads = Runtime.getRuntime().availableProcessors();

        final ExecutorService executorService = Executors.newFixedThreadPool(nThreads);

        List<HardWork> taskList = getTasks(50);

        final List<Future<Long>> resultList = executorService.invokeAll(taskList);
        System.out.println("Ready");

        for (Future<Long> future : resultList) {
            final Long fibonacciNumber = future.get();
            System.out.println(NumberFormat.getNumberInstance().format(fibonacciNumber));
        }

        executorService.shutdown();
    }

    private static List<HardWork> getTasks(int hardestOne) {

        final ArrayList<HardWork> tasks = new ArrayList<>();
        for (int i = 0; i < hardestOne; i++) {
            tasks.add(new HardWork(i));
        }
        return Collections.unmodifiableList(tasks);
    }

    private static class HardWork implements Callable<Long> {

        private final int n;

        public HardWork(int n) {

            this.n = n;
        }

        @Override
        public Long call() {

            return fibonacci(n);
        }

        private Long fibonacci(int n) {

            if (n < 2) {
                return (long) n;
            }
            return fibonacci(n - 1) + fibonacci(n - 2);
        }
    }
}

Jak lepiej opracujesz taski, to dostaniesz inne rezultaty. Na przykład Fibonancci nie rekurencyjnie a iteracyjnie w mig policzy aż do przepełnienia Long.

private Long fibonacci(int n) {

            Long[] fibonacci = new Long[n + 2];
            fibonacci[0] = 0L;
            fibonacci[1] = 1L;

            for (int i = 2; i <= n; i++) {
                fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2];
            }

            return fibonacci[n];
        }

Jeszcze jedno

 final List<Future<Long>> resultList = executorService.invokeAll(taskList);

blokuje wykonanie wątku main dopóki wszystkie Future nie bedą gotowe.
A submit to puszczenie wątku bez blokowania dalszego natychmiastowego wykonania main
Zobacz kiedy pojawi się "Ready" wypisane przez main w pierwszym i drugim przypadku
invoke jest operacją blokującą, puści dalej dopiero gdy wszystkie Future będą gotowe
submit jest operacją nieblokująca, puszcza Thread do executorService i na nic nie czeka

package com.app;

import lombok.SneakyThrows;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;

public class Example {

    @SneakyThrows
    public static void main(String[] args) {

        int nThreads = Runtime.getRuntime().availableProcessors();

        final ExecutorService executorService = Executors.newFixedThreadPool(nThreads);

        List<HardWork> taskList = getTasks(44);

        for (HardWork hardWork : taskList) {
            executorService.submit(hardWork);
        }

        System.out.println("Ready");

        executorService.shutdown();
    }

    private static List<HardWork> getTasks(int hardestOne) {

        final ArrayList<HardWork> tasks = new ArrayList<>();
        for (int i = 0; i < hardestOne; i++) {
            tasks.add(new HardWork(i));
        }
        return Collections.unmodifiableList(tasks);
    }

    private static class HardWork implements Callable<Void> {

        private final int n;

        public HardWork(int n) {

            this.n = n;
        }

        @Override
        public Void call() {

            System.out.println(NumberFormat.getNumberInstance().format(fibonacci(n)));

            return null;
        }

        private Long fibonacci(int n) {

            if (n < 2) {
                return (long) n;
            }
            return fibonacci(n - 1) + fibonacci(n - 2);
        }
    }
}

Przeanalizuj sobie te dwa przykłady, powinny ci pomóc trochę to zrozumieć

3

JVM nie kontroluje użycia CPU (jest to zasób kontrolowany przez OS). W zależności od systemu operacyjnego możesz skorzystać z różnych rozwiązań ograniczających użycie CPU per proces.
W Windows masz magiczne polecenie START, które posiada kilka parametrów pozwalających ograniczyć użyciu CPU.
screenshot-20210222092747.png

Możesz proces JVM uruchomić przez:

start /BELOWNORMAL /AFFINITY 0x15  java.exe ... 

Przypiszesz w ten sposób procesory 1,3 i 5 do procesu, a dodatkowo proces dostanie niższy priorytete w dostępie do CPU.

Pod Linuksem można wykorzystać cgroups i zdefiniować usługę w ramach systemd. Usłudze możesz przyznać tyle % CPU ile uznasz za stosowne.

0

@yarel:
No a jak będzie coś jak ForkJoinPool i stealing?
I z zewnątrz narzucać ograniczenia, jakby aplikacja chodziła nie na serwerze a na laptopie i film się zacinał?
Nie bardzo rozumiem, by przy wymagającej aplikacji, nie miała ona dedykowanego serwera.

1 użytkowników online, w tym zalogowanych: 0, gości: 1