Tiesiog „Java“

Paskaitykite Java - gimusi žlugti  ir  Javos sukaktuvės

Pastaba: Šis puslapis buvo parengtas 1996.04.12. Kai kurie vertinimai palikti iš to laiko – jie palikti kaip istorinis to meto kontekstas; patys spręskite, kiek tebeaktualūs tie samprotavimai. Šiuo metu puslapis buvo peržiūrėtas ir patikslintas.

Pasaulyje šiuo metu yra apie 15 mln. programuotojų. Iš jų per 9 mln. sakėsi bent dalį laiko skyrę programavimui „Java“ kalba. Tad „Java“ – yra labiausiai naudojama programavim kalba pasaulyje.

„Java“.
Jos pradžia buvo 1991 m. vadinantis „Oak”, esant dalimi „Sun” projekto, kurio tikslas buvo sukurti programavimo kalbą, kuri užpildytų spragą tarp valdomų prietaisų (pvz., kasetinių magnetofonų ar televizorių). James Gosling‘o*) vadovaujama „Green“ komanda siekė sukurti kalbą, kuri tiktų prietaisams su skirtingais procesoriais.

Pradinis tikslas žlugo nesusitarus su prietaisų gamintojais. „Green“ komanda privalėjo rasti naują rinką savo kalbai. Laimei, išpopuliarėjo Internetas ir „Oak“ kalba puikiai tiko „web“ komponenčių kūrimui. Tie nedideli programiniai vienetai, vadinami apletais, tapo pradine „Oak“ naudojimo niša. Didelis proveržis įvyko 1995 m., kai „Netscape“ įtraukė „Java“ į savo naršyklę.

Objektinis programavimas prasidėjo su SIMULA-67 (1967) kalba ir persikėlė į populiarias kalbas, pvz., C++. C++ įtakojo daugelį „Java” koncepcijų.

Pavadinimo kilmė

Iš pradžių šią kalbą James Gosling'as vadino „Oak“ (išvertus, „ąžuolas“), nes pro jo „Sun“ ofiso langą matėsi didelis ąžuolas. Tačiau vėliau buvo pastebėta, kad taip jau buvo vadinama kita programavimo kalba. Ir visų nuostabai, buvo nepaprastai surasti tinkamą pavadinimą, - „Green“ komanda praleido nemaža valandų svarstydama įvairius variantus. O vieną dieną pavadinimas „šovė į galvą“, beeinant į vietinę kavos parduotuvytę.

Ir manau teisingai, nes „Java“ žymiai skambesnė, negu ne anglui svetimas žodis „Oak“ (Ach tie amerikonai, manantys, kad visas pasaulis vien tik vograuja angliškai). O „laukiniui“ lietuviui (t.y. man) iš kart prieš akis „stojasi“ paplūdimiai ir pusnuogės moterys...

Kokia ji, ta gražuolė?

„Java“ labai panaši į C++, tačiau yra daug paprastesnė. Išmestos visos _nebūtinos_ galimybės: nėra operacijų polimorfiškumo, aprašų failų, preprocesoriaus, veiksmų su nuorodomis, struktūrų, kelių matavimų masyvų ir t.t. Ir tereikia šiek tiek žinoti C/C++ arba „Pascal“, ir galite dumti pirmyn. Štai klasikines „Labas, pasauli!“ pavyzdėlis:

public class LabasJava {
   public static void main ( String argv[] ) 
     System.out.println ("Labas, Java!");
   }
}

Gražu?!

Kaip veikia „Java“ programos?

Štai kaip tai įsivaizduoja James Gosling'as (žmogus, prieš 1990-ais parašęs „Emacs“):
Tai va! Paruošta programa registruojama serveryje. Ir kai vartotojas pasiunčia užklausą: „Ei, o kaip atrodo tas puslapiukas?“ - pradeda sunktis nurodytas puslapiukas. O jame „įsiūta“ „Java“ programa, kuri apsižiūrėjus pyksta: „Ei vaikine, šioje vietoje turi būti va toksai filmukas! Ar jo nėra vietoje? Ech, ne - tada važiuojam į serverį jo pasiimti!“ Ir man visai nerūpi, kur jis yra - Valstijose ar Zimbabvėje - programa jį suras automatiškai.

Kuo pasižymi?

Pirmiausia, „Java“ laikoma objektine kalba. Beveik viskas, išskyrus skaičius, joje yra objektai, realizuojami naudojant klases. Kiekviena klasė yra metodų, aprašančių objekto elgseną, aibė. Neatmetamos ir sąsajos, kurios leidžia naudoti objektus nesirūpinant, kaip objektai yra realizuoti. „Java“ sąsajos yra panašios į IDL sąsajas, o tai reiškia, kad ji pritaikoma CORBA modeliui.

Be to, „Java“ programos gali turėti kelias gijas (threads). Ne paslaptis, kad programuoti kelių procesų valdymą nėra lengva (tai visai ne tas pats, kaip „tiesiog išgerti stiklinę vandens“), tačiau „Java“ supaprastina jų sinchronizacijos mechanizmus. Realiai, „Java“ gijos tiesiogiai atvaizduojamos į terpės gijas.

Ir kiekvienas pastebės, kad nereikia rūpintis atminties valdymu. Išskyrus atminties sritį, nebūtina ją atlaisvinti. „Šiukšlių surinkimo“ programa automatiškai tikrina ir sistemai sugrąžina nenaudojamus atminties resursus. Ir t.t. ir t.t. Tiesiog rožinė pasaka žvelgiant pro rožinius akinius.

Ar viskas gražu?

Pati „Java“ kalba nėra stebuklas, nors visi ir tekalba tik apie ją! Juk „Ką galiu parašyti su C++, - galiu ir su 'Java'. Ir atvirkščiai!“ (J. Gosling). Taigi vertybė ne kalba, o jos programų naudojimo technologija! Juk programą aš galiu parašyti ir C/C++, „Pascal“ ar „Visual Basic“ (kas, beja, jau įmanoma su „Visual Script“), - tereikia turėti kompiliatorių į „bytecode“. Ir neabejoju, kad jie greitai atsiras!

Taip pat drįstu nesutikti ir su teiginiu, kad tai labai saugi kalba. Aš esu didelis „blogiukas“ ir savajame puslapyje galiu paslėpti didelę „blogybę“. Visi, kurie užsuks į šį puslapį, pasičiups ir manąją „dovanėlę“. Štai tą patį kalba ir ekspertai. O štai „Symantec“ paskelbė, kad ji jau sukūrė pirmąją virusų paieškos programą „Java“ virusams. JĖGA, ar ne? - juk dar nežinoma, ar egzistuoja „Java“ virusai!

Keista taip pat girdėti, kad „Java“ programos labai stabilios. Iš tikro, jos tėra tiek stabilios, kiek terpė, kurioje jos yra vykdomos. Jei terpė neleidžia pažeisti (arba pati nepažeidžia) sistemos resursų, - tai juk terpės, o ne „Java“ privalumas. Bet ar matėte programą be klaidų?

Yra dar daug klausimiukų, bet palikime kol kas juos ateičiai. O tuo metu priminsiu problemėlę, kuri iškilo arabams dėl JAV prezidento rinkiminės kompanijos. Bob Dole pavardė rašoma lygiai taip pat kaip persų kalbos žodis reiškiantis žmogaus organą, kuris lotyniškai vadinamas penis. Įsivaizduokite, kaip, jam laimėjus, skambėtų laikraščių antraštės: „JAV prezidentu tapo B..is!“ Kur ten „Java“ problemoms!


*) Džeimsas Goslingas (James Gosling, g. 1955 m.) – kanadiečių kompiuterininkas, plačiausiai žinomas kaip vienas „Java“ kalbos projektuotųjų (kai dirbo „Sun Microsystems“; 1984-2010), o taip pat sukūrė langų valdymo sistemą „NeWS“, „Gosling Emacs“ (1981) bei buvo vienas „Star Seven“ kūrėjų. 2011-2017 m. dirbo „Liquid Robotics“ (kurią vėliau įsigijo „Boeing Defense“), kūrusią robototechnikos sprendimus vandenyno tyrinėjimams. Vėliau pradėjo dirbti „Amazon Web Services“. Vienas arba su bendraautoriais yra parašęs keletą knygų apie „Java“.

Kaip pradėti?

Labai paprasta – atsisiunčiate ir įsidiegiate reikiamą „Java SDK“ (pvz., „Java SE“ iš www.oracle.com/java). Su „Java SE“ gausite:
* „Java“ „runtime“ aplinką (JRE);
* „Java“ virtualiąją mašiną (JVM) naudojamai platformai;
* naudojamos platformos bibliotekas;
* „Java“ kompiliatorių;
* papildomas utilitas (pvz., archyvo (JAR) sukūrimui; klaidų paieškai ir kt.);
* kodo pavyzdžius.

Su JDK jau galite kompiliuoti ir vykdyti savo programas.
O kad būtų patogiau, naudinga turėti ir programavimo aplinkas (IDE), pvz., „Eclipse“, suteikiančias vizualias priemones, palengvinančias programų kūrimą, jų platinimą ir kt.

Po to, kai prsisiuntėme JDK, galime pabandyti vykdyti pirmąją mūsų programą.
Programos tekstą įrašome į tekstinį failą vardu LabasJava.java

Kompiliuojama:
javac LabasJava.java

Sukompiliavus kataloge atsiras failas LabasJava.class
Dabar jį galima vykdyti komanda:
java LabasJava

Ir ji išduos pranešimą:
Labas, Java!


Pateiksime trumpą instrukciją, kaip sukurti ir patikrinti šią programą „Eclipse“ aplinkoje (nurodyta pagal Eclipse Java EE Luna 4.4.1 versiją):

Kuriame naują Java projektą: File -> New -> Java project

Duodam vardą projektui: LabasJava
Spaudžiam mygtuką Finish

LabasJava projekto grupėje ties katalogu src vykdom:
New -> Class
Priskiriame klasės vardą: LabasJava
Žemiau nurodome (uždedame varnelę, kad reikia sukurti main metodą (ties public static void main (String[] args))
Spaudžiam mygtuką Finish

main metode įrašome:
System.out.println ("Labas, Java!");

Išsaugome ir vykdome:
Run -> Run As -> Java Application

Console lange turi pateikti pranešimą:
Labas, Java!

Java virtualios gijos  

„Java“ kalbos virtualios gijos leidžia programos resursus iškelti į JVM. Jos įtrauktos į „Java 19“ versiją ir yra JVM dalimi nuo „Java 20“. Čia jas pristatysime „Java 21“ kontekste.

Virtualios gijos (threads) yra abstrakcijos sluoksnis tarp programos lygio lygiagretumo ir operacinės sistemos procesų; kitaip sakant, JVM atlieka tarpininko vaidmenį tarp OS ir programos. Programa sukuria virtualias gijas, o JVM priskiria kompiuterio resursus jų vykdymui. Tai skiriasi nuo įprastinių gijų (threads), kurie tiesiogiai susiejami su OS procesais; ir programos kodas yra atsakingas už resursų suteikimą ir paskirstymą. Virtualių gijų atveju, programa sukuria virtualias gijas taip išreikšdama poreikį lygiagrečiam vykdymui, tačiau OS resursus gauna ir skirsto JVM. JVM resursus paskiria tik tada, kai virtuali gija yra priparkuota, t.y. pasiruošusi veikti ir laukia resursų. Taigi, virtualios gijos yra sudėtinga gijų pulo forma.

Įprastų gijų atveju, jei serveris laukia užklausos, OS gija irgi laukia, kas labai riboja serverių išplečiamumą. Anksčiau efektyvumą ir išplečiamumą buvo bandoma spręsti asinchronines bibliotekas, pvz., „JavaRX“.

Ir nors virtualios gijos visiškai pakeičia JVM veikimo būdą, pats programos kodas išlieka nepaprastai panašus į įprastinių gijų naudojimą – tad ir ankstesnio kodo pritaikymas virtualioms gijoms labai lengvas. O vadinamasis struktūrinis lygiagretumas leidžia labiau sutelkti dėmesį į logiką, o ne gijų tvarkymą.

Pabandykime virtualias gijas paaiškinti pavyzdžiu. Norėdami jį išbandyti, naudokite bent 21 versijos JVM.

package com.vartiklis;

import java.util.Random;

public class Programa {
  public static void main( String[] args ) {
    boolean vThreads = args.length > 0;
    System.out.println( "Virtualios gijos naudojamos: " + vThreads);

    long start = System.currentTimeMillis();

    Random random = new Random();
    Runnable runnable = () -> { double d = random.nextDouble(1000) % random.nextDouble(1000);  };  
    for (long i = 0; i < 90000; i++){
      if (vThreads){ 
        Thread.startVirtualThread(runnable);
      } else {
        Thread t = new Thread(runnable);
        t.start();
      }
    }
   
    long finish = System.currentTimeMillis();
    long timeElapsed = finish - start;
    System.out.println("Vykdymo laikas: " + timeElapsed);
  }
}

Kaip matote, virtualios gijos sukūrimui naudojama Thread.startVirtualThread(runnable) kad yra įprastinių gijų thread.start() pakeitimas. Jei programa naudojama su argumentu, ji naudos virtualias gijas, jei be – įprastines gijas. Išbandykite abu atvejus ir pamatysite skirtumą – naudojant virtualias gijas programa įvykdoma daugiau nei 30 greičiau.

Pastaba: yra ir kitų būdų pradėti virtualią, pvz. tebenaudojant Thread su Thread.ofVirtual().start(runnable).
Yra dar vienas visiškai skirtingas būdas virtualios gijos pradėjimui – naudojant ExecutorService, t.y. panaudojant:
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();

Galima panaudoti ir struktūrinės konkurencijos konstruktą, pvz.,
     try (var scope = new StructuredTaskScope()) {
          for (int id : visiID) {
            scope.fork(() -> getExternalData(id));      
          } 
          scope.join(); // laukti pabaigimo
     } catch (Exception e) {
          System.out.println("Klaida: " + e);
     }

Tačiau yra skirtumų tame, kaip geriausiai turėtų būti naudojamos virtualios gijos. Jos visad yra demonai (daemon), t.y. laiko JVM procesus tol, kol baigia darbą. Be to, negalima pakeisti jų prioritetų.

Ir reikia atminti, kad virtualios gijos nėra orientuotos į daug skaičiavimų reikalaujančius darbus – čia jų efektyvumas gali būto mažesnis. Jos labiau tinka IO orientuotiems darbams. Ir jei reikia milijonų gijų, įprastinės gijos suvalgys visą atmintį, o virtualios gijos - vos kelis MB.


Ateities kalbos?
JavaScript pradmenys
Java - gimusi žlugti
Anotacijos Java kalboje
Gležnas Java standarto daigelis
Programavimo kalbų klegesys
Lambda išraiškos – Java į naują lygį
Paveldimumas, kompozicija ir polimorfizmas
AWK kalba - sena ir nuolat aktuali
Pirmasis „Java“ įskiepis Lietuvoje
Įvadas į Perl kalbą: Kas naudoja Perl?
Programavimo kalbų istorija
Dygios JavaScript eilutės
Anotacijos Java kalboje
Java 8: Optional prieš null
Iš kur Javos tas lėtumas?
Unix komandinės eilutė
Tiesa apie REST
Ruby on Rails
Tcl kalba
Pirmoji programa
NSO skiltis
Vartiklis