நூல்கள் எவ்வாறு தொடர்பு கொள்கின்றன என்பதற்கான விவரங்களின் சுருக்கமான கண்ணோட்டம். முன்னதாக, நூல்கள் எவ்வாறு ஒன்றோடொன்று ஒத்திசைக்கப்படுகின்றன என்பதைப் பார்த்தோம். இந்த நேரத்தில், நூல்கள் தொடர்பு கொள்ளும்போது ஏற்படக்கூடிய சிக்கல்களில் மூழ்கி, அவற்றை எவ்வாறு தவிர்ப்பது என்பதைப் பற்றி பேசுவோம். மேலும் ஆழமான ஆய்வுக்கு சில பயனுள்ள இணைப்புகளையும் வழங்குவோம்.
JVisualVM செருகுநிரல் நிறுவப்பட்டிருந்தால் (கருவிகள் -> செருகுநிரல்கள் வழியாக), முட்டுக்கட்டை எங்கு ஏற்பட்டது என்பதைக் காணலாம்:
JVisualVM இன் கூற்றுப்படி, நாம் தூங்கும் காலங்களையும் பூங்காவின் காலத்தையும் பார்க்கிறோம் (இது ஒரு நூல் பூட்டைப் பெற முயற்சிக்கும் போது - அது பூங்கா நிலைக்கு நுழைகிறது, நாங்கள் முன்பு நூல் ஒத்திசைவு பற்றி பேசியபோது விவாதித்தது போல ) . லைவ்லாக்கின் உதாரணத்தை நீங்கள் இங்கே பார்க்கலாம்: ஜாவா - த்ரெட் லைவ்லாக் .
நீங்கள் ஒரு சிறந்த உதாரணத்தை இங்கே பார்க்கலாம்: ஜாவா - நூல் பட்டினி மற்றும் நேர்மை . இந்த உதாரணம் பட்டினியின் போது நூல்களுக்கு என்ன நடக்கிறது மற்றும் ஒரு சிறிய மாற்றம் எவ்வாறு சுமையை சமமாக விநியோகிக்க உதவுகிறது என்பதைக்
![ஒன்றாகச் சிறந்தது: ஜாவா மற்றும் நூல் வகுப்பு. பகுதி III — தொடர்பு - 7]()

அறிமுகம்
எனவே, ஜாவாவில் நூல்கள் இருப்பதை நாம் அறிவோம். சிறந்த ஒன்றாக: ஜாவா மற்றும் நூல் வகுப்பு என்ற தலைப்பில் நீங்கள் அதைப் பற்றி படிக்கலாம் . பகுதி I - மரணதண்டனையின் நூல்கள் . மேலும் சிறந்த ஒன்றாக: ஜாவா மற்றும் த்ரெட் கிளாஸ் என்ற தலைப்பில் த்ரெட்கள் ஒன்றோடொன்று ஒத்திசைக்க முடியும் என்பதை நாங்கள் ஆராய்ந்தோம் . பகுதி II - ஒத்திசைவு . நூல்கள் ஒன்றோடு ஒன்று எவ்வாறு தொடர்பு கொள்கின்றன என்பதைப் பற்றி பேச வேண்டிய நேரம் இது. பகிரப்பட்ட ஆதாரங்களை அவர்கள் எவ்வாறு பகிர்ந்து கொள்கிறார்கள்? இங்கே என்ன பிரச்சினைகள் ஏற்படலாம்?
முட்டுக்கட்டை
எல்லாவற்றிலும் பயங்கரமான பிரச்சனை முட்டுக்கட்டை. டெட்லாக் என்பது இரண்டு அல்லது அதற்கு மேற்பட்ட இழைகள் மற்றொன்றிற்காக நித்தியமாக காத்திருக்கும் போது. முட்டுக்கட்டையை விவரிக்கும் Oracle வலைப்பக்கத்திலிருந்து ஒரு உதாரணத்தை எடுப்போம் :public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s bowed back to me!%n",
this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alphonse = new Friend("Alphonse");
final Friend gaston = new Friend("Gaston");
new Thread(() -> alphonse.bow(gaston)).start();
new Thread(() -> gaston.bow(alphonse)).start();
}
}
முட்டுக்கட்டை இங்கு முதன்முறையாக நிகழாமல் இருக்கலாம், ஆனால் உங்கள் நிரல் செயலிழந்தால், இயக்க வேண்டிய நேரம் இது jvisualvm
: 
"Thread-1" - Thread t@12
java.lang.Thread.State: BLOCKED
at Deadlock$Friend.bowBack(Deadlock.java:16)
- waiting to lock <33a78231> (a Deadlock$Friend) owned by "Thread-0" t@11
நூல் 0 இலிருந்து பூட்டுக்காக நூல் 1 காத்திருக்கிறது. அது ஏன் நடக்கிறது? Thread-1
இயங்கத் தொடங்குகிறது மற்றும் Friend#bow
முறையை செயல்படுத்துகிறது. இது முக்கிய சொல்லுடன் குறிக்கப்பட்டுள்ளது , அதாவது (தற்போதைய பொருள்) synchronized
மானிட்டரைப் பெறுகிறோம் . this
முறையின் உள்ளீடு மற்ற பொருளைக் குறிக்கும் Friend
. இப்போது, Thread-1
மறுபுறம் முறையை இயக்க விரும்புகிறது Friend
, மேலும் அவ்வாறு செய்ய அதன் பூட்டைப் பெற வேண்டும். ஆனால் மற்ற நூல் (இந்த வழக்கில் Thread-0
) முறையை உள்ளிட முடிந்தால் bow()
, பூட்டு ஏற்கனவே பெறப்பட்டு Thread-1
காத்திருக்கிறதுThread-0
, மற்றும் நேர்மாறாகவும். இது முட்டுக்கட்டை என்பது தீர்க்க முடியாதது, இதை முட்டுக்கட்டை என்கிறோம். விடுபட முடியாத மரணப் பிடியைப் போல, முட்டுக்கட்டை என்பது உடைக்க முடியாத பரஸ்பர தடுப்பு. முட்டுக்கட்டை பற்றிய மற்றொரு விளக்கத்திற்கு, இந்த வீடியோவை நீங்கள் பார்க்கலாம்: டெட்லாக் மற்றும் லைவ்லாக் விளக்கப்பட்டது .
லைவ்லாக்
முட்டுக்கட்டை என்றால், லைவ்லாக் கூட இருக்கிறதா? ஆம், உள்ளது :) லைவ்லாக் நிகழ்கிறது, த்ரெட்கள் வெளிப்புறமாக உயிருடன் இருப்பது போல் தோன்றும், ஆனால் அவர்களால் எதையும் செய்ய முடியவில்லை, ஏனெனில் அவர்கள் தங்கள் வேலையைத் தொடர தேவையான நிபந்தனைகளை (கள்) பூர்த்தி செய்ய முடியாது. அடிப்படையில், லைவ்லாக் என்பது டெட்லாக் போன்றது, ஆனால் த்ரெட்கள் மானிட்டருக்காகக் காத்திருக்காது. மாறாக, அவர்கள் எப்போதும் எதையாவது செய்துகொண்டே இருக்கிறார்கள். உதாரணத்திற்கு:import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class App {
public static final String ANSI_BLUE = "\u001B[34m";
public static final String ANSI_PURPLE = "\u001B[35m";
public static void log(String text) {
String name = Thread.currentThread().getName(); // Like "Thread-1" or "Thread-0"
String color = ANSI_BLUE;
int val = Integer.valueOf(name.substring(name.lastIndexOf("-") + 1)) + 1;
if (val != 0) {
color = ANSI_PURPLE;
}
System.out.println(color + name + ": " + text + color);
try {
System.out.println(color + name + ": wait for " + val + " sec" + color);
Thread.currentThread().sleep(val * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Lock first = new ReentrantLock();
Lock second = new ReentrantLock();
Runnable locker = () -> {
boolean firstLocked = false;
boolean secondLocked = false;
try {
while (!firstLocked || !secondLocked) {
firstLocked = first.tryLock(100, TimeUnit.MILLISECONDS);
log("First Locked: " + firstLocked);
secondLocked = second.tryLock(100, TimeUnit.MILLISECONDS);
log("Second Locked: " + secondLocked);
}
first.unlock();
second.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
new Thread(locker).start();
new Thread(locker).start();
}
}
இந்த குறியீட்டின் வெற்றியானது ஜாவா த்ரெட் ஷெட்யூலர் எந்த வரிசையில் த்ரெட்களைத் தொடங்குகிறார் என்பதைப் பொறுத்தது. முதலில் தொடங்கினால் Thead-1
, லைவ்லாக் கிடைக்கும்:
Thread-1: First Locked: true
Thread-1: wait for 2 sec
Thread-0: First Locked: false
Thread-0: wait for 1 sec
Thread-0: Second Locked: true
Thread-0: wait for 1 sec
Thread-1: Second Locked: false
Thread-1: wait for 2 sec
Thread-0: First Locked: false
Thread-0: wait for 1 sec
...
எடுத்துக்காட்டில் இருந்து நீங்கள் பார்க்க முடியும் என, இரண்டு நூல்களும் இரண்டு பூட்டுகளையும் பெற முயற்சி செய்கின்றன, ஆனால் அவை தோல்வியடைகின்றன. ஆனால், அவை முட்டுக்கட்டையில் இல்லை. வெளிப்புறமாக, எல்லாம் நன்றாக இருக்கிறது, அவர்கள் தங்கள் வேலையைச் செய்கிறார்கள். 
பட்டினி
டெட்லாக் மற்றும் லைவ்லாக் தவிர, மல்டித்ரெடிங்கின் போது ஏற்படும் மற்றொரு பிரச்சனையும் உள்ளது: பட்டினி. இந்த நிகழ்வு த்ரெட்கள் தடுக்கப்படாத முந்தைய வடிவங்களில் இருந்து வேறுபட்டது - அவை போதுமான ஆதாரங்களைக் கொண்டிருக்கவில்லை. இதன் விளைவாக, சில த்ரெட்கள் அனைத்து செயலாக்க நேரத்தையும் எடுக்கும் போது, மற்றவற்றை இயக்க முடியவில்லை:
https://www.logicbig.com/
Thread.sleep()
காட்டுகிறது .Thread.wait()

இனம் நிலைமைகள்
மல்டித்ரெடிங்கில், "இன நிலை" போன்ற ஒரு விஷயம் உள்ளது. நூல்கள் ஒரு ஆதாரத்தைப் பகிரும்போது இந்த நிகழ்வு நிகழ்கிறது, ஆனால் குறியீடு சரியான பகிர்வை உறுதிப்படுத்தாத வகையில் எழுதப்பட்டுள்ளது. ஒரு உதாரணத்தைப் பாருங்கள்:public class App {
public static int value = 0;
public static void main(String[] args) {
Runnable task = () -> {
for (int i = 0; i < 10000; i++) {
int oldValue = value;
int newValue = ++value;
if (oldValue + 1 != newValue) {
throw new IllegalStateException(oldValue + " + 1 = " + newValue);
}
}
};
new Thread(task).start();
new Thread(task).start();
new Thread(task).start();
}
}
இந்தக் குறியீடு முதல் முறை பிழையை உருவாக்காமல் இருக்கலாம். அவ்வாறு செய்யும்போது, இது போல் தோன்றலாம்:
Exception in thread "Thread-1" java.lang.IllegalStateException: 7899 + 1 = 7901
at App.lambda$main$0(App.java:13)
at java.lang.Thread.run(Thread.java:745)
நீங்கள் பார்க்கிறபடி, newValue
ஒரு மதிப்பை ஒதுக்கும்போது ஏதோ தவறு ஏற்பட்டது. newValue
மிகவும் பெரியது. value
ரேஸ் நிலை காரணமாக, இரண்டு ஸ்டேட்மெண்ட்களுக்கு இடையே உள்ள மாறிகளை மாற்ற இழைகளில் ஒன்று முடிந்தது . நூல்களுக்கு இடையில் ஒரு இனம் உள்ளது என்று மாறிவிடும். பண பரிவர்த்தனைகளில் இதுபோன்ற தவறுகளைச் செய்யாமல் இருப்பது எவ்வளவு முக்கியம் என்பதை இப்போது யோசித்துப் பாருங்கள்... எடுத்துக்காட்டுகள் மற்றும் வரைபடங்களை இங்கே காணலாம்: ஜாவா நூலில் இன நிலையை உருவகப்படுத்துவதற்கான குறியீடு .
எளிதில் ஆவியாகிற
நூல்களின் தொடர்பு பற்றி பேசுகையில்,volatile
முக்கிய வார்த்தை குறிப்பிடத் தக்கது. ஒரு எளிய உதாரணத்தைப் பார்ப்போம்:
public class App {
public static boolean flag = false;
public static void main(String[] args) throws InterruptedException {
Runnable whileFlagFalse = () -> {
while(!flag) {
}
System.out.println("Flag is now TRUE");
};
new Thread(whileFlagFalse).start();
Thread.sleep(1000);
flag = true;
}
}
மிகவும் சுவாரஸ்யமாக, இது வேலை செய்யாது. புதிய நூல் புலத்தில் மாற்றத்தைக் காணாது flag
. புலத்தில் இதைச் சரிசெய்ய flag
, நாம் முக்கிய சொல்லைப் பயன்படுத்த வேண்டும் volatile
. எப்படி, ஏன்? செயலி அனைத்து செயல்களையும் செய்கிறது. ஆனால் கணக்கீடுகளின் முடிவுகள் எங்காவது சேமிக்கப்பட வேண்டும். இதற்கு, மெயின் மெமரி உள்ளது மற்றும் செயலியின் கேச் உள்ளது. ஒரு செயலியின் தற்காலிக சேமிப்புகள் மெயின் மெமரியை அணுகுவதை விட விரைவாக தரவை அணுக பயன்படும் ஒரு சிறிய நினைவகம் போன்றது. ஆனால் எல்லாவற்றுக்கும் ஒரு குறைபாடு உள்ளது: தற்காலிக சேமிப்பில் உள்ள தரவு புதுப்பித்த நிலையில் இல்லாமல் இருக்கலாம் (மேலே உள்ள எடுத்துக்காட்டில், கொடி புலத்தின் மதிப்பு புதுப்பிக்கப்படாதபோது). அதனால்volatile
முக்கிய வார்த்தை JVM க்கு எங்கள் மாறியை கேச் செய்ய விரும்பவில்லை என்று கூறுகிறது. இது அனைத்து த்ரெட்களிலும் புதுப்பித்த முடிவைக் காண அனுமதிக்கிறது. இது மிகவும் எளிமையான விளக்கம். முக்கிய சொல்லைப் பொறுத்தவரை , இந்த கட்டுரையைப்volatile
படிக்குமாறு நான் மிகவும் பரிந்துரைக்கிறேன் . மேலும் தகவலுக்கு, Java Memory Model மற்றும் Java Volatile Keyword ஆகியவற்றைப் படிக்கவும் நான் உங்களுக்கு அறிவுறுத்துகிறேன் . கூடுதலாக, இது தெரிவுநிலையைப் பற்றியது என்பதை நினைவில் கொள்வது அவசியம் , மாற்றங்களின் அணுவைப் பற்றியது அல்ல. "பந்தய நிலைமைகள்" பிரிவில் உள்ள குறியீட்டைப் பார்க்கும்போது, IntelliJ IDEA இல் ஒரு உதவிக்குறிப்பைக் காண்போம்: இந்த ஆய்வு IDEA-61117 வெளியீட்டின் ஒரு பகுதியாக IntelliJ IDEA இல் சேர்க்கப்பட்டது , இது 2010 இல் வெளியிடப்பட்ட குறிப்புகளில் பட்டியலிடப்பட்டது .volatile


அணுசக்தி
அணு செயல்பாடுகள் பிரிக்க முடியாத செயல்பாடுகள். எடுத்துக்காட்டாக, ஒரு மாறிக்கு மதிப்பை ஒதுக்கும் செயல்பாடு அணுவாக இருக்க வேண்டும். துரதிர்ஷ்டவசமாக, அதிகரிப்பு செயல்பாடு அணு அல்ல, ஏனெனில் அதிகரிப்புக்கு மூன்று CPU செயல்பாடுகள் தேவை: பழைய மதிப்பைப் பெறவும், அதில் ஒன்றைச் சேர்க்கவும், பின்னர் மதிப்பைச் சேமிக்கவும். அணுசக்தி ஏன் முக்கியமானது? அதிகரிப்புச் செயல்பாட்டின் மூலம், ரேஸ் நிலை இருந்தால், பகிரப்பட்ட ஆதாரம் (அதாவது பகிரப்பட்ட மதிப்பு) எந்த நேரத்திலும் திடீரென்று மாறலாம். கூடுதலாக, 64-பிட் கட்டமைப்புகளை உள்ளடக்கிய செயல்பாடுகள், எடுத்துக்காட்டாகlong
மற்றும் double
, அணு அல்ல. மேலும் விவரங்களை இங்கே படிக்கலாம்: 64-பிட் மதிப்புகளைப் படிக்கும்போதும் எழுதும்போதும் அணுசக்தியை உறுதிசெய்யவும் . அணுசக்தி தொடர்பான சிக்கல்களை இந்த எடுத்துக்காட்டில் காணலாம்:
public class App {
public static int value = 0;
public static AtomicInteger atomic = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
Runnable task = () -> {
for (int i = 0; i < 10000; i++) {
value++;
atomic.incrementAndGet();
}
};
for (int i = 0; i < 3; i++) {
new Thread(task).start();
}
Thread.sleep(300);
System.out.println(value);
System.out.println(atomic.get());
}
}
சிறப்பு AtomicInteger
வகுப்பில் எப்போதும் 30,000 வழங்கப்படும், ஆனால் அது value
அவ்வப்போது மாறும். இந்த தலைப்பின் ஒரு சிறிய கண்ணோட்டம் உள்ளது: ஜாவாவில் அணு மாறிகள் அறிமுகம் . "ஒப்பிடுதல் மற்றும் இடமாற்று" அல்காரிதம் அணு வகுப்புகளின் மையத்தில் உள்ளது. லாக்-ஃப்ரீ அல்காரிதம்களின் ஒப்பீடு - CAS மற்றும் FAA இல் JDK 7 மற்றும் 8 இன் உதாரணம் அல்லது விக்கிபீடியாவில் உள்ள Compare-and-swap கட்டுரையில் இதைப் பற்றி மேலும் படிக்கலாம் .
http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html
நிகழும்-முன்
"முன்பு நடக்கும்" என்று ஒரு சுவாரஸ்யமான மற்றும் மர்மமான கருத்து உள்ளது. நூல்களைப் பற்றிய உங்கள் ஆய்வின் ஒரு பகுதியாக, அதைப் பற்றி நீங்கள் படிக்க வேண்டும். நடக்கும்-முன் உறவு, இழைகளுக்கு இடையேயான செயல்கள் எந்த வரிசையில் பார்க்கப்படும் என்பதைக் காட்டுகிறது. பல விளக்கங்களும் வர்ணனைகளும் உள்ளன. இந்த விஷயத்தில் சமீபத்திய விளக்கக்காட்சிகளில் ஒன்று இங்கே: ஜாவா "நடக்கும்-முன்" உறவுகள் .சுருக்கம்
இந்த மதிப்பாய்வில், நூல்கள் எவ்வாறு தொடர்பு கொள்கின்றன என்பதற்கான சில விவரங்களை நாங்கள் ஆராய்ந்தோம். ஏற்படக்கூடிய சிக்கல்கள் மற்றும் அவற்றைக் கண்டறிந்து அகற்றுவதற்கான வழிகள் பற்றி நாங்கள் விவாதித்தோம். தலைப்பில் கூடுதல் பொருட்களின் பட்டியல்:- இருமுறை சரிபார்க்கப்பட்ட பூட்டுதல்
- JSR 133 (ஜாவா மெமரி மாடல்) அடிக்கடி கேட்கப்படும் கேள்விகள்
- IQ 35: முட்டுக்கட்டையை எவ்வாறு தடுப்பது?
- டக்ளஸ் ஹாக்கின்ஸ் (2017) எழுதிய ஜாவாவில் கன்கரன்சி கான்செப்ட்ஸ்
GO TO FULL VERSION