Cum funcționează în lumea java
Cum funcționează în lumea de Java. Piscina Subiect 9
- 11.04.17 06:48 •
- kuptservol •
- • # 326146
- • Habrahabr
- Tutorial •
- 9 •
- 5600
- cum ar fi Forbes, doar mai bine.
Principiul de bază de programare este: nu reinventeze roata. Dar, uneori, pentru a înțelege ce se întâmplă și cum să utilizați instrumentul în mod corespunzător, trebuie să o facem. Astăzi inventa sarcini model multithreaded.
Imaginați-vă că aveți care cauzează o sarcină grea pe procesor:
Ne dorim cât mai curând posibil, să se ocupe de un număr de sarcini, încercați să *:
Pe roaba mea cu 4 nuclee fizice ale resurselor procesorului -pid top:efectuarea de 104 secunde.
După cum puteți vedea, descărcarea unui singur procesor pe un singur java proces cu un fir de rulare este de 100%, dar utilizarea procesorului de ansamblu în spațiul utilizator este de doar 2,5%, și avem o mulțime de resurse de sistem neutilizate.
Să încercăm să utilizați mai mult, adăugarea de mai multe fire lucrător:
ThreadPoolExecutor
Pentru a accelera, am folosit ThreadPool - java în ThreadPoolExecutor său rol, care pot fi puse în aplicare, fie direct, fie de la una dintre metodele din clasa Utilities. Dacă ne uităm în interiorul ThreadPoolExecutor, putem găsi un loc:
în care sarcinile se întâmplă, dacă rulați mai multe fire decât dimensiunea piscinei inițiale. Dacă executați mai mică decât dimensiunea inițială a piscinei fluxurilor piscina va încerca să înceapă un nou fir:
Fiecare addWorker începe un nou fir de sarcina Runnable că sondajele workQueue pentru sarcini noi și le execută.
ThreadPoolExecutor are un javadoc foarte clar, astfel încât nu are sens să parafrazez. În schimb, să încercăm să facem propriul nostru:
Acum, să îndeplinească aceeași sarcină ca mai sus, cu piscina noastră.
Schimbarea liniei în MultithreadClient:
Termenul de execuție este aproape la fel - 15 secunde.
fluxuri de dimensiune pool
Să încercăm să crească și mai mult numărul de fire care rulează în piscina - 100.
Putem vedea că timpul de execuție a crescut la 28 de secunde - de ce sa întâmplat asta?
Există mai multe motive independente de ce performanță ar putea cădea, de exemplu, din cauza contextului procesorului constantă comută când se oprește de lucru pe o singură sarcină și ar trebui să fie trecut la alta, de comutare implică salvarea statului și starea de recuperare. Atâta timp cât procesorul. starea de comutare ocupat, nu face nici o lucrare utilă pe o sarcină.
Numărul de switch-uri de context proces poate fi ușor de observat la setările din producția CSW echipe de top.
Cum de a alege dimensiunea piscinei?
Dimensiunea depinde de tipul de sarcini îndeplinite. Desigur, dimensiunea piscina fir ar trebui să fie rareori zahardokozhen, mai degrabă ar trebui să fie personalizabil și afișează dimensiunea optimă a sarcinilor de monitorizare executabile lățime de bandă.
Presupunând că fluxurile nu se blochează reciproc, nu există nici O așteptați starea / I, și timpul de procesare sarcină este același, un bazin fir optim = Runtime.getRuntime (). AvailableProcessors () + 1.
În cazul în care fluxurile în principal așteptat I / O, dimensiunea optimă a piscinei trebuie crescută cu relația dintre procesul de latență și timpul de calcul. De exemplu. Avem un proces care cheltuiește 50% din iowait timp, atunci mărimea piscinei poate fi de 2 * Runtime.getRuntime (). AvailableProcessors () + 1.
Alte tipuri de bazine
piscina fir cu limită de memorie, care blochează trimiterea problemei, atunci când în coada de așteptare prea multe sarcini MemoryAwareThreadPoolExecutor
JMXEnabledThreadPoolExecutor
Puteți găsi codul sursă aici.