Nawet pojedynczy procesor może robić "wiele rzeczy w tym samym czasie" w luźnym sensie, ale nie są one naprawdę równoległe. Możesz uruchomić 100 wątków, aby uruchomić na pojedynczym rdzeniu, a oni otrzymają fragmenty czasu, podczas których każdy z nich może uruchomić kilka instrukcji, tworząc wrażenie, że wszystkie są wykonywane w tym samym czasie.
Jak mówiłem w innym SO postu: multithreading on dual core machine?
Określenie wątków zwykle obejmuje trzy warstwy abstrakcji:
- nici Obsługi są wątki rozpoczęte przez aplikacje i są odwzorowane N: M, aby :
- jądra nici są nićmi, które obsługiwanych przez system operacyjny odwzorowywane N M do:
- Wątki sprzętowe, które są faktycznymi dostępnymi zasobami fizycznymi.
Nitki Java to wątki użytkownika. 4 rdzenie twojego CPU liczą się jako wątki sprzętowe. Ponieważ mapowanie ma wartość N: M między warstwami, można zauważyć, że istnieje kilka wątków użytkowników odwzorowanych na mniejszą liczbę wątków sprzętowych.
Teraz, powiedział to, nie są na ogół dwa rodzaje działań nici, każdy z własnymi dziwactw:
- I/O wątków: nici te spędzają większość swojego czasu oczekiwania na odczyt/zapis operacje ze strumienia i są w międzyczasie zablokowane (nie są planowane do wykonania, dopóki nie pojawi się zdarzenie, aby je obudzić). Na procesorze jest światło i wiele z nich może działać jednocześnie, nawet na jednym rdzeniu.
- Nić obliczeniowa: ten wątek wykonuje wiele zgrzytnięć i maksymalnie wykorzystuje procesor. Zaczynając więcej niż (2x liczba dostępnych rdzeni), takie wątki obniżą wydajność, ponieważ procesor ma ograniczoną liczbę jednostek funkcjonalnych: jednostki ALU, jednostki FPU itp.
Druga klasa wątków powyżej pozwala naprawdę widzisz korzyści lub uruchamiasz wielowątkowy program java na twoim czterordzeniowym procesorze. Oto prosty przykład programu, który wykonuje kwadratury 1.000.000.000 numerami pierwszy sekwencyjnie, a następnie równolegle przy użyciu puli wątków z 4 Odpowiedź:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
class ThreadTask implements Runnable {
private int total = 0;
public ThreadTask(int total) {
this.total = total;
}
@Override
public void run() {
int value = 0;
for(int i = 0; i < total; i++) {
value = i * i;
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
int total = 1000000000;
long start = System.currentTimeMillis();
long value = 0;
for(int i = 0; i < total; i++) {
value = i * i;
}
long stop = System.currentTimeMillis();
System.out.println((stop - start) + " ms");
ExecutorService exec = Executors.newFixedThreadPool(4);
start = System.currentTimeMillis();
for(int i = 0; i < 4; i++) {
exec.submit(new ThreadTask(total/4));
}
exec.shutdown();
exec.awaitTermination(10, TimeUnit.SECONDS);
stop = System.currentTimeMillis();
System.out.println((stop - start) + " ms");
}
}
Zapraszam do regulacji wartości total
czy to działa zbyt szybko . Teraz pracuję na netbooku z Intel Atom, więc nie jest to naprawdę szybkie.
Następnie dodano znacznik wielowątkowości - to nie jest tylko pytanie skoncentrowane na Javie. Mam nadzieję, że otrzymasz wspaniałe odpowiedzi. – Makoto
Artykuł, który przeczytałeś, pochodzi prawdopodobnie z czasów przed procesorami wielordzeniowymi, więc stwierdza, że tylko komputer wieloprocesorowy może go używać. – Hurda