CodeGym/Java Blog/Random/Nangungunang 50 tanong at sagot sa panayam sa trabaho par...
John Squirrels
Antas
San Francisco

Nangungunang 50 tanong at sagot sa panayam sa trabaho para sa Java Core. Bahagi 2

Nai-publish sa grupo
Nangungunang 50 tanong at sagot sa panayam sa trabaho para sa Java Core. Bahagi 1Nangungunang 50 tanong at sagot sa panayam sa trabaho para sa Java Core.  Bahagi 2 - 1

Multithreading

24. Paano ako lilikha ng bagong thread sa Java?

Sa isang paraan o iba pa, ang isang thread ay nilikha gamit ang klase ng Thread. Ngunit may iba't ibang paraan para gawin ito...
  1. Magmana ng java.lang.Thread .
  2. Ipatupad ang java.lang.Runnable interface — ang constructor ng klase ng Thread ay kumukuha ng Runnable object.
Pag-usapan natin ang bawat isa sa kanila.

Magmana ng klase ng Thread

Sa kasong ito, ginagawa naming magmana ang aming klase ng java.lang.Thread . Mayroon itong run() na pamamaraan, at iyon lang ang kailangan namin. Ang lahat ng buhay at lohika ng bagong thread ay nasa pamamaraang ito. Ito ay uri ng tulad ng isang pangunahing pamamaraan para sa bagong thread. Pagkatapos nito, ang natitira lamang ay lumikha ng isang bagay ng aming klase at tawagan ang start() na pamamaraan. Gagawa ito ng bagong thread at magsisimulang isagawa ang lohika nito. Tignan natin:
/**
* An example of how to create threads by inheriting the {@link Thread} class.
*/
class ThreadInheritance extends Thread {

   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName());
   }

   public static void main(String[] args) {
       ThreadInheritance threadInheritance1 = new ThreadInheritance();
       ThreadInheritance threadInheritance2 = new ThreadInheritance();
       ThreadInheritance threadInheritance3 = new ThreadInheritance();
       threadInheritance1.start();
       threadInheritance2.start();
       threadInheritance3.start();
   }
}
Ang output ng console ay magiging katulad nito:
Thread-1 Thread-0 Thread-2
Iyon ay, kahit dito nakikita natin na ang mga thread ay naisakatuparan hindi sa pagkakasunud-sunod, ngunit sa halip na nakikita ng JVM na angkop na patakbuhin ang mga ito :)

Ipatupad ang Runnable na interface

Kung ikaw ay laban sa inheritance at/o nagmana na ng ibang klase, maaari mong gamitin ang java.lang.Runnable na interface. Dito, ginagawa namin ang aming klase na ipatupad ang interface na ito sa pamamagitan ng pagpapatupad ng run() na pamamaraan, tulad ng sa halimbawa sa itaas. Ang natitira na lang ay lumikha ng mga bagay sa Thread . Mukhang mas malala ang mas maraming linya ng code. Ngunit alam natin kung gaano nakapipinsala ang mana at mas mabuting iwasan ito sa lahat ng paraan ;) Tingnan mo:
/**
* An example of how to create threads from the {@link Runnable} interface.
* It's easier than easy — we implement this interface and then pass an instance of our object
* to the constructor.
*/
class ThreadInheritance implements Runnable {

   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName());
   }

   public static void main(String[] args) {
       ThreadInheritance runnable1 = new ThreadInheritance();
       ThreadInheritance runnable2 = new ThreadInheritance();
       ThreadInheritance runnable3 = new ThreadInheritance();

       Thread threadRunnable1 = new Thread(runnable1);
       Thread threadRunnable2 = new Thread(runnable2);
       Thread threadRunnable3 = new Thread(runnable3);

       threadRunnable1.start();
       threadRunnable2.start();
       threadRunnable3.start();
   }
}
At narito ang resulta:
Thread-0 Thread-1 Thread-2

25. Ano ang pagkakaiba sa pagitan ng isang proseso at isang thread?

Nangungunang 50 tanong at sagot sa panayam sa trabaho para sa Java Core.  Bahagi 2 - 2Magkaiba ang proseso at thread sa mga sumusunod na paraan:
  1. Ang isang tumatakbong programa ay tinatawag na isang proseso, ngunit ang isang thread ay isang piraso ng isang proseso.
  2. Ang mga proseso ay independyente, ngunit ang mga thread ay mga piraso ng isang proseso.
  3. Ang mga proseso ay may iba't ibang mga puwang ng address sa memorya, ngunit ang mga thread ay nagbabahagi ng isang karaniwang espasyo ng address.
  4. Ang paglipat ng konteksto sa pagitan ng mga thread ay mas mabilis kaysa sa paglipat sa pagitan ng mga proseso.
  5. Ang inter-process na komunikasyon ay mas mabagal at mas mahal kaysa sa inter-thread na komunikasyon.
  6. Ang anumang mga pagbabago sa isang proseso ng magulang ay hindi nakakaapekto sa isang proseso ng bata, ngunit ang mga pagbabago sa isang thread ng magulang ay maaaring makaapekto sa isang thread ng bata.

26. Ano ang mga pakinabang ng multithreading?

  1. Ang multithreading ay nagbibigay-daan sa isang application/program na palaging tumutugon sa input, kahit na ito ay nagpapatakbo na ng ilang mga gawain sa background;
  2. Ginagawang posible ng multithreading na makumpleto ang mga gawain nang mas mabilis, dahil ang mga thread ay tumatakbo nang nakapag-iisa;
  3. Nagbibigay ang multithreading ng mas mahusay na paggamit ng memorya ng cache, dahil maaaring ma-access ng mga thread ang nakabahaging mapagkukunan ng memorya;
  4. Binabawasan ng multithreading ang bilang ng mga server na kinakailangan, dahil ang isang server ay maaaring magpatakbo ng maraming mga thread nang sabay-sabay.

27. Ano ang mga estado sa ikot ng buhay ng isang thread?

Nangungunang 50 tanong at sagot sa panayam sa trabaho para sa Java Core.  Bahagi 2 - 3
  1. Bago: Sa ganitong estado, nilikha ang Thread object gamit ang bagong operator, ngunit wala pang bagong thread. Hindi magsisimula ang thread hangga't hindi natin tinatawag ang start() method.
  2. Runnable: Sa ganitong estado, ang thread ay handa nang tumakbo pagkatapos ng start() tinatawag na pamamaraan. Gayunpaman, hindi pa ito napipili ng thread scheduler.
  3. Tumatakbo: Sa ganitong estado, ang thread scheduler ay pumili ng isang thread mula sa isang handa na estado, at ito ay tumatakbo.
  4. Naghihintay/Naka-block: sa ganitong estado, ang isang thread ay hindi tumatakbo, ngunit ito ay buhay pa rin o naghihintay para sa isa pang thread na makumpleto.
  5. Dead/Terminated: kapag lumabas ang thread sa run() method, ito ay nasa dead o terminated state.

28. Posible bang magpatakbo ng thread nang dalawang beses?

Hindi, hindi namin mai-restart ang isang thread, dahil pagkatapos magsimula at tumakbo ang isang thread, mapupunta ito sa Dead state. Kung susubukan naming magsimula ng thread nang dalawang beses, itatapon ang isang java.lang.IllegalThreadStateException . Tignan natin:
class DoubleStartThreadExample extends Thread {

   /**
    * Simulate the work of a thread
    */
   public void run() {
	// Something happens. At this state, this is not essential.
   }

   /**
    * Start the thread twice
    */
   public static void main(String[] args) {
       DoubleStartThreadExample doubleStartThreadExample = new DoubleStartThreadExample();
       doubleStartThreadExample.start();
       doubleStartThreadExample.start();
   }
}
Magkakaroon ng exception sa sandaling dumating ang execution sa pangalawang simula ng parehong thread. Subukan ito sa iyong sarili ;) Mas mahusay na makita ito nang isang beses kaysa marinig ang tungkol dito nang isang daang beses.

29. Paano kung direktang tatawagan mo ang run() nang hindi tumatawag sa start()?

Oo, maaari mong tiyak na tawagan ang run() na pamamaraan, ngunit ang isang bagong thread ay hindi malilikha, at ang pamamaraan ay hindi tatakbo sa isang hiwalay na thread. Sa kasong ito, mayroon kaming isang ordinaryong bagay na tinatawag na isang ordinaryong pamamaraan. Kung pinag-uusapan natin ang start() na pamamaraan, isa pang usapin iyon. Kapag tinawag ang pamamaraang ito, magsisimula ang JVM ng bagong thread. This thread, in turn, calls our method ;) Huwag maniwala? Narito, subukan ito:
class ThreadCallRunExample extends Thread {

   public void run() {
       for (int i = 0; i < 5; i++) {
           System.out.print(i);
       }
   }

   public static void main(String args[]) {
       ThreadCallRunExample runExample1 = new ThreadCallRunExample();
       ThreadCallRunExample runExample2 = new ThreadCallRunExample();

       // Two ordinary methods will be called in the main thread, one after the other.
       runExample1.run();
       runExample2.run();
   }
}
At ang output ng console ay magiging ganito:
0123401234
Tulad ng nakikita mo, walang thread na ginawa. Ang lahat ay gumana tulad ng sa isang ordinaryong klase. Una, ang paraan ng unang bagay ay naisakatuparan, at pagkatapos ay ang pangalawa.

30. Ano ang thread ng daemon?

Ang daemon thread ay isang thread na nagsasagawa ng mga gawain sa mas mababang priyoridad kaysa sa isa pang thread. Sa madaling salita, ang trabaho nito ay magsagawa ng mga pantulong na gawain na kailangang gawin lamang kasabay ng isa pang (pangunahing) thread. Mayroong maraming mga daemon thread na awtomatikong tumatakbo, tulad ng koleksyon ng basura, finalizer, atbp.

Bakit tinatapos ng Java ang isang thread ng daemon?

Ang tanging layunin ng daemon thread ay magbigay ng suporta sa background sa thread ng isang user. Alinsunod dito, kung ang pangunahing thread ay winakasan, ang JVM ay awtomatikong magwawakas sa lahat ng mga daemon thread nito.

Mga pamamaraan ng klase ng Thread

Ang java.lang.Thread class ay nagbibigay ng dalawang pamamaraan para sa pagtatrabaho sa isang daemon thread:
  1. public void setDaemon(boolean status) — Isinasaad ng paraang ito kung magiging daemon thread ito. Ang default ay false . Nangangahulugan ito na walang mga daemon thread na gagawin maliban kung partikular mong sabihin ito.
  2. public boolean isDaemon() — Ang pamamaraang ito ay mahalagang getter para sa daemon variable, na itinakda namin gamit ang nakaraang pamamaraan.
Halimbawa:
class DaemonThreadExample extends Thread {

   public void run() {
       // Checks whether this thread is a daemon
       if (Thread.currentThread().isDaemon()) {
           System.out.println("daemon thread");
       } else {
           System.out.println("user thread");
       }
   }

   public static void main(String[] args) {
       DaemonThreadExample thread1 = new DaemonThreadExample();
       DaemonThreadExample thread2 = new DaemonThreadExample();
       DaemonThreadExample thread3 = new DaemonThreadExample();

       // Make thread1 a daemon thread.
       thread1.setDaemon(true);

       System.out.println("daemon? " + thread1.isDaemon());
       System.out.println("daemon? " + thread2.isDaemon());
       System.out.println("daemon? " + thread3.isDaemon());

       thread1.start();
       thread2.start();
       thread3.start();
   }
}
Output ng console:
demonyo? totoong daemon? huwad na demonyo? maling daemon thread user thread user thread
Mula sa output, nakikita natin na sa loob mismo ng thread, maaari nating gamitin ang static currentThread() na paraan upang malaman kung aling thread ito. Bilang kahalili, kung mayroon kaming reference sa thread object, maaari din naming malaman nang direkta mula dito. Nagbibigay ito ng kinakailangang antas ng pagsasaayos.

31. Posible bang gawing isang daemon ang isang thread pagkatapos itong malikha?

Hindi. Kung susubukan mong gawin ito, makakakuha ka ng IllegalThreadStateException . Nangangahulugan ito na maaari lamang tayong lumikha ng isang daemon thread bago ito magsimula. Halimbawa:
class SetDaemonAfterStartExample extends Thread {

   public void run() {
       System.out.println("Working...");
   }

   public static void main(String[] args) {
       SetDaemonAfterStartExample afterStartExample = new SetDaemonAfterStartExample();
       afterStartExample.start();

       // An exception will be thrown here
       afterStartExample.setDaemon(true);
   }
}
Output ng console:
Gumagana... Exception sa thread na "main" java.lang.IllegalThreadStateException sa java.lang.Thread.setDaemon(Thread.java:1359) at SetDaemonAfterStartExample.main(SetDaemonAfterStartExample.java:14)

32. Ano ang shutdown hook?

Ang shutdown hook ay isang thread na tahasang tinatawag bago isara ang Java virtual machine (JVM). Kaya, maaari naming gamitin ito upang maglabas ng isang mapagkukunan o mag-save ng estado kapag ang Java virtual machine ay nag-shut down nang normal o hindi normal. Maaari kaming magdagdag ng shutdown hook gamit ang sumusunod na paraan:
Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());
Gaya ng ipinapakita sa halimbawa:
/**
* A program that shows how to start a shutdown hook thread,
* which will be executed right before the JVM shuts down
*/
class ShutdownHookThreadExample extends Thread {

   public void run() {
       System.out.println("shutdown hook executed");
   }

   public static void main(String[] args) {

       Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());

       System.out.println("Now the program is going to fall asleep. Press Ctrl+C to terminate it.");
       try {
           Thread.sleep(60000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
   }
}
Output ng console:
Ngayon ang programa ay matutulog na. Pindutin ang Ctrl+C upang wakasan ito. isinagawa ang shutdown hook

33. Ano ang synchronization?

Sa Java, ang pag-synchronize ay ang kakayahang kontrolin ang maramihang mga thread sa pag-access sa anumang nakabahaging mapagkukunan. Kapag sinubukan ng maraming thread na gawin ang parehong gawain nang sabay-sabay, maaari kang makakuha ng hindi tamang resulta. Upang ayusin ang problemang ito, gumagamit ang Java ng pag-synchronize, na nagbibigay-daan lamang sa isang thread na tumakbo sa isang pagkakataon. Maaaring makamit ang pag-synchronize sa tatlong paraan:
  • Pag-synchronize ng isang pamamaraan
  • Pag-synchronize ng isang partikular na bloke
  • Static na pag-synchronize

Pag-synchronize ng isang pamamaraan

Ang isang naka-synchronize na paraan ay ginagamit upang i-lock ang isang bagay para sa anumang nakabahaging mapagkukunan. Kapag ang isang thread ay tumawag ng isang naka-synchronize na paraan, awtomatiko nitong nakukuha ang lock ng bagay at ilalabas ito kapag natapos na ng thread ang gawain nito. Upang magawa ito, kailangan mong idagdag ang naka-synchronize na keyword. Makikita natin kung paano ito gumagana sa pamamagitan ng pagtingin sa isang halimbawa:
/**
* An example where we synchronize a method. That is, we add the synchronized keyword to it.
* There are two authors who want to use one printer. Each of them has composed their own poems
* And of course they don’t want their poems mixed up. Instead, they want work to be performed in * * * order for each of them
*/
class Printer {

   synchronized void print(List<String> wordsToPrint) {
       wordsToPrint.forEach(System.out::print);
       System.out.println();
   }

   public static void main(String args[]) {
       // One object for two threads
       Printer printer  = new Printer();

       // Create two threads
       Writer1 writer1 = new Writer1(printer);
       Writer2 writer2 = new Writer2(printer);

       // Start them
       writer1.start();
       writer2.start();
   }
}

/**
* Author No. 1, who writes an original poem.
*/
class Writer1 extends Thread {
   Printer printer;

   Writer1(Printer printer) {
       this.printer = printer;
   }

   public void run() {
       List<string> poem = Arrays.asList("I ", this.getName(), " Write", " A Letter");
       printer.print(poem);
   }

}

/**
* Author No. 2, who writes an original poem.
*/
class Writer2 extends Thread {
   Printer printer;

   Writer2(Printer printer) {
       this.printer = printer;
   }

   public void run() {
       List<String> poem = Arrays.asList("I Do Not ", this.getName(), " Not Write", " No Letter");
       printer.print(poem);
   }
}
At ang output ng console ay ito:
I Thread-0 Sumulat ng Liham Hindi Ko Thread-1 Hindi Sumulat ng Walang Liham

Block ng pag-synchronize

Ang isang naka-synchronize na bloke ay maaaring gamitin upang magsagawa ng pag-synchronize sa anumang partikular na mapagkukunan sa isang paraan. Sabihin natin na sa isang malaking paraan (oo, hindi mo dapat isulat ang mga ito, ngunit kung minsan ay nangyayari ito) kailangan mong i-synchronize lamang ang isang maliit na seksyon para sa ilang kadahilanan. Kung ilalagay mo ang lahat ng code ng pamamaraan sa isang naka-synchronize na bloke, gagana ito katulad ng isang naka-synchronize na paraan. Ang syntax ay ganito ang hitsura:
synchronized ("object to be locked") {
   // The code that must be protected
}
Upang maiwasang maulit ang nakaraang halimbawa, gagawa kami ng mga thread gamit ang mga anonymous na klase, ibig sabihin, agad naming ipapatupad ang Runnable interface.
/**
* This is how a synchronization block is added.
* Inside the block, you need to specify which object's mutex will be acquired.
*/
class Printer {

   void print(List<String> wordsToPrint) {
       synchronized (this) {
           wordsToPrint.forEach(System.out::print);
       }
       System.out.println();
   }

   public static void main(String args[]) {
       // One object for two threads
       Printer printer = new Printer();

       // Create two threads
       Thread writer1 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("I ", "Writer1", " Write", " A Letter");
               printer.print(poem);
           }
       });
       Thread writer2 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("I Do Not ", "Writer2", " Not Write", " No Letter");
               printer.print(poem);
           }
       });

       // Start them
       writer1.start();
       writer2.start();
   }
}

}
At ang output ng console ay ito:
Ako Manunulat1 Sumulat ng Liham Hindi Ko Sumulat2 Hindi Sumulat ng Walang Liham

Static na pag-synchronize

Kung gumawa ka ng isang static na pamamaraan na naka-synchronize, pagkatapos ay ang pag-lock ang mangyayari sa klase, hindi ang bagay. Sa halimbawang ito, nagsasagawa kami ng static na pag-synchronise sa pamamagitan ng paglalapat ng naka-synchronize na keyword sa isang static na paraan:
/**
* This is how a synchronization block is added.
* Inside the block, you need to specify which object's mutex will be acquired.
*/
class Printer {

   static synchronized void print(List<String> wordsToPrint) {
       wordsToPrint.forEach(System.out::print);
       System.out.println();
   }

   public static void main(String args[]) {

       // Create two threads
       Thread writer1 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("I ", "Writer1", " Write", " A Letter");
               Printer.print(poem);
           }
       });
       Thread writer2 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("I Do Not ", "Writer2", " Not Write", " No Letter");
               Printer.print(poem);
           }
       });

       // Start them
       writer1.start();
       writer2.start();
   }
}
At ang output ng console ay ito:
Hindi Ako Manunulat2 Hindi Sumulat Walang Liham Ko Manunulat1 Sumulat ng Liham

34. Ano ang volatile variable?

Sa multithreaded programming, ginagamit ang pabagu-bagong keyword para sa kaligtasan ng thread. Kapag ang isang nababagong variable ay binago, ang pagbabago ay makikita ng lahat ng iba pang mga thread, kaya ang isang variable ay maaaring gamitin ng isang thread sa isang pagkakataon. Sa pamamagitan ng paggamit ng pabagu-bagong keyword, maaari mong garantiya na ang isang variable ay thread-safe at nakaimbak sa nakabahaging memorya, at hindi ito iimbak ng mga thread sa kanilang mga cache. Anong itsura nito?
private volatile AtomicInteger count;
Nagdagdag lang kami ng volatile sa variable. Ngunit tandaan na hindi ito nangangahulugan ng kumpletong kaligtasan ng thread... Pagkatapos ng lahat, ang mga operasyon sa variable ay maaaring hindi atomic. Iyon ay sinabi, maaari mong gamitin ang mga klase ng Atomic na gumagawa ng mga operasyon nang atomically, ibig sabihin, sa isang pagtuturo ng CPU. Maraming ganoong klase sa java.util.concurrent.atomic package.

35. Ano ang deadlock?

Sa Java, ang deadlock ay isang bagay na maaaring mangyari bilang bahagi ng multithreading. Maaaring magkaroon ng deadlock kapag ang isang thread ay naghihintay para sa lock ng isang bagay na nakuha ng isa pang thread, at ang pangalawang thread ay naghihintay para sa lock ng object na nakuha ng unang thread. Nangangahulugan ito na ang dalawang thread ay naghihintay para sa isa't isa, at ang pagpapatupad ng kanilang code ay hindi maaaring magpatuloy. Nangungunang 50 tanong at sagot sa panayam sa trabaho para sa Java Core.  Bahagi 2 - 4Isaalang-alang natin ang isang halimbawa na mayroong klase na nagpapatupad ng Runnable. Ang tagabuo nito ay tumatagal ng dalawang mapagkukunan. Ang run() na paraan ay nakakakuha ng lock para sa kanila sa pagkakasunud-sunod. Kung gagawa ka ng dalawang bagay ng klase na ito, at ipapasa mo ang mga mapagkukunan sa ibang pagkakasunud-sunod, madali kang mapupunta sa deadlock:
class DeadLock {

   public static void main(String[] args) {
       final Integer r1 = 10;
       final Integer r2 = 15;

       DeadlockThread threadR1R2 = new DeadlockThread(r1, r2);
       DeadlockThread threadR2R1 = new DeadlockThread(r2, r1);

       new Thread(threadR1R2).start();
       new Thread(threadR2R1).start();
   }
}

/**
* A class that accepts two resources.
*/
class DeadlockThread implements Runnable {

   private final Integer r1;
   private final Integer r2;

   public DeadlockThread(Integer r1, Integer r2) {
       this.r1 = r1;
       this.r2 = r2;
   }

   @Override
   public void run() {
       synchronized (r1) {
           System.out.println(Thread.currentThread().getName() + " acquired resource: " + r1);

           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }

           synchronized (r2) {
               System.out.println(Thread.currentThread().getName() + " acquired resource: " + r2);
           }
       }
   }
}
Output ng console:
Nakuha ng unang thread ang unang mapagkukunan Nakuha ng pangalawang thread ang pangalawang mapagkukunan

36. Paano mo maiiwasan ang deadlock?

Dahil alam natin kung paano nangyayari ang deadlock, makakagawa tayo ng ilang konklusyon...
  • Sa halimbawa sa itaas, ang deadlock ay nangyayari dahil sa katotohanan na mayroon kaming nested locking. Iyon ay, mayroon kaming isang naka-synchronize na bloke sa loob ng isang naka-synchronize na bloke. Upang maiwasan ito, sa halip na pugad, kailangan mong lumikha ng bagong mas mataas na abstraction layer, ilipat ang pag-synchronize sa mas mataas na antas, at alisin ang nested locking.
  • Ang mas maraming pag-lock ang gagawin mo, mas malamang na magkakaroon ng deadlock. Samakatuwid, sa bawat oras na magdagdag ka ng naka-synchronize na bloke, kailangan mong isipin kung talagang kailangan mo ito at kung maiiwasan mo ang pagdaragdag ng bago.
  • Gamit ang Thread.join() . Maaari ka ring magkaroon ng deadlock habang naghihintay ang isang thread para sa isa pa. Para maiwasan ang problemang ito, maaari mong isaalang-alang ang pagtatakda ng timeout para sa join() method.
  • Kung mayroon kaming isang thread, pagkatapos ay walang deadlock ;)

37. Ano ang kondisyon ng lahi?

Kung ang mga karera sa totoong buhay ay nagsasangkot ng mga kotse, ang mga karera sa multithreading ay nagsasangkot ng mga thread. Pero bakit? :/ Mayroong dalawang thread na tumatakbo at maaaring ma-access ang parehong bagay. At maaari nilang subukang i-update ang estado ng nakabahaging object nang sabay. Ang lahat ay malinaw sa ngayon, tama ba? Isinasagawa ang mga thread sa literal na kahanay (kung ang processor ay may higit sa isang core) o sunud-sunod, na ang processor ay naglalaan ng interleaved time slices. Hindi namin maaaring pamahalaan ang mga prosesong ito. Nangangahulugan ito na kapag ang isang thread ay nagbabasa ng data mula sa isang bagay hindi namin magagarantiya na magkakaroon ito ng oras upang baguhin ang bagay BAGO gawin ito ng ibang thread. Ang ganitong mga problema ay lumitaw kapag mayroon kaming mga "check-and-act" na combo. Anong ibig sabihin niyan? Ipagpalagay na mayroon tayong if statement na ang katawan ay nagbabago sa mismong if-condition, halimbawa:
int z = 0;

// Check
if (z < 5) {
// Act
   z = z + 5;
}
Maaaring sabay na ipasok ng dalawang thread ang code block na ito kapag ang z ay zero pa rin at pagkatapos ay maaaring baguhin ng parehong thread ang halaga nito. Bilang resulta, hindi namin makukuha ang inaasahang halaga na 5. Sa halip, makakakuha kami ng 10. Paano mo ito maiiwasan? Kailangan mong kumuha ng lock bago suriin at kumilos, at pagkatapos ay bitawan ang lock pagkatapos. Iyon ay, kailangan mong ipasok ang unang thread sa if block, gawin ang lahat ng mga aksyon, baguhin z , at pagkatapos lamang bigyan ang susunod na thread ng pagkakataon na gawin ang parehong. Ngunit ang susunod na thread ay hindi papasok sa if block, dahil ang z ay magiging 5 na:
// Acquire the lock for z
if (z < 5) {
   z = z + 5;
}
// Release z's lock
===================================================

Sa halip na isang konklusyon

Gusto kong magpasalamat sa lahat ng nagbasa hanggang dulo. Malayo pa, pero nagtiis ka! Siguro hindi malinaw ang lahat. Ito ay normal. Noong una kong sinimulan ang pag-aaral ng Java, hindi ko maiikot ang aking utak sa kung ano ang isang static na variable. Pero no big deal. Natulog ako dito, nagbasa ng ilan pang mga mapagkukunan, at pagkatapos ay dumating ang pagkaunawa. Ang paghahanda para sa isang pakikipanayam ay higit na isang pang-akademikong tanong sa halip na isang praktikal na tanong. Bilang resulta, bago ang bawat panayam, dapat mong suriin at i-refresh sa iyong memorya ang mga bagay na maaaring hindi mo madalas gamitin.

At gaya ng nakasanayan, narito ang ilang kapaki-pakinabang na link:

Salamat sa lahat ng nagbabasa. See you soon :) Aking GitHub profileNangungunang 50 tanong at sagot sa panayam sa trabaho para sa Java Core.  Bahagi 2 - 5
Mga komento
  • Sikat
  • Bago
  • Luma
Dapat kang naka-sign in upang mag-iwan ng komento
Wala pang komento ang page na ito