మల్టీథ్రెడింగ్ ద్వారా సమస్యలు పరిష్కరించబడతాయి
మల్టీథ్రెడింగ్ వాస్తవానికి రెండు ముఖ్యమైన లక్ష్యాలను సాధించడానికి కనుగొనబడింది:-
ఒకే సమయంలో అనేక పనులు చేయండి.
పై ఉదాహరణలో, వివిధ థ్రెడ్లు (కుటుంబ సభ్యులు) సమాంతరంగా అనేక చర్యలను చేసారు: వారు వంటలను కడుగుతారు, దుకాణానికి వెళ్లి వస్తువులను ప్యాక్ చేశారు.
ప్రోగ్రామింగ్కు మరింత దగ్గరి సంబంధం ఉన్న ఉదాహరణను మేము అందించగలము. మీకు వినియోగదారు ఇంటర్ఫేస్తో ప్రోగ్రామ్ ఉందని అనుకుందాం. మీరు ప్రోగ్రామ్లో 'కొనసాగించు' క్లిక్ చేసినప్పుడు, కొన్ని గణనలు జరుగుతాయి మరియు వినియోగదారు కింది స్క్రీన్ని చూడాలి. ఈ చర్యలు వరుసగా జరిగితే, వినియోగదారు 'కొనసాగించు' బటన్ను క్లిక్ చేసిన తర్వాత ప్రోగ్రామ్ ఆగిపోతుంది. ప్రోగ్రామ్ అన్ని అంతర్గత గణనలను నిర్వహించి, వినియోగదారు ఇంటర్ఫేస్ రిఫ్రెష్ చేయబడిన భాగానికి చేరుకునే వరకు వినియోగదారు 'కొనసాగించు' బటన్ స్క్రీన్తో స్క్రీన్ను చూస్తారు.
సరే, మేము కొన్ని నిమిషాలు వేచి ఉంటాము!
లేదా మేము మా ప్రోగ్రామ్ను మళ్లీ పని చేయవచ్చు లేదా, ప్రోగ్రామర్లు చెప్పినట్లుగా, దానిని 'సమాంతరం' చేయవచ్చు. ఒక థ్రెడ్పై మన గణనలను నిర్వహిస్తాము మరియు మరొకదానిపై వినియోగదారు ఇంటర్ఫేస్ను గీయండి. చాలా కంప్యూటర్లు దీన్ని చేయడానికి తగినంత వనరులను కలిగి ఉన్నాయి. మేము ఈ మార్గాన్ని తీసుకుంటే, ప్రోగ్రామ్ స్తంభింపజేయదు మరియు వినియోగదారు లోపల ఏమి జరుగుతుందో చింతించకుండా స్క్రీన్ల మధ్య సాఫీగా కదులుతారు. ఒకటి మరొకటి జోక్యం చేసుకోదు :)
-
గణనలను మరింత వేగంగా జరుపుము.
ఇక్కడ ప్రతిదీ చాలా సులభం. మా ప్రాసెసర్కు బహుళ కోర్లు ఉంటే మరియు ఈ రోజు చాలా ప్రాసెసర్లు ఉంటే, అనేక కోర్లు మా టాస్క్ల జాబితాను సమాంతరంగా నిర్వహించగలవు. సహజంగానే, మనం 1000 టాస్క్లు చేయవలసి వస్తే మరియు ఒక్కొక్కటి సెకను తీసుకుంటే, ఒక కోర్ 1000 సెకన్లలో జాబితాను పూర్తి చేయగలదు, రెండు కోర్లు 500 సెకన్లలో, మూడు 333 సెకన్ల కంటే కొంచెం ఎక్కువ.
public class MyFirstThread extends Thread {
@Override
public void run() {
System.out.println("I'm Thread! My name is " + getName());
}
}
థ్రెడ్లను సృష్టించడానికి మరియు అమలు చేయడానికి, మేము ఒక తరగతిని సృష్టించాలి, దానిని java.lang వారసత్వంగా పొందేలా చేయాలి . థ్రెడ్ క్లాస్, మరియు దాని రన్() పద్ధతిని భర్తీ చేయండి. ఆ చివరి అవసరం చాలా ముఖ్యమైనది. ఇది రన్() పద్ధతిలో మన థ్రెడ్ని అమలు చేయడానికి లాజిక్ను నిర్వచించాము. ఇప్పుడు, మనం MyFirstThread యొక్క ఉదాహరణను సృష్టించి, అమలు చేస్తే , run() పద్ధతి పేరుతో ఒక లైన్ను ప్రదర్శిస్తుంది: getName() పద్ధతి థ్రెడ్ యొక్క 'సిస్టమ్' పేరును ప్రదర్శిస్తుంది, ఇది స్వయంచాలకంగా కేటాయించబడుతుంది. కానీ మనం ఎందుకు తాత్కాలికంగా మాట్లాడుతున్నాము? ఒకదాన్ని సృష్టించి తెలుసుకుందాం!
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
MyFirstThread thread = new MyFirstThread();
thread.start();
}
}
}
కన్సోల్ అవుట్పుట్: నేను థ్రెడ్! నా పేరు థ్రెడ్-2 నేను థ్రెడ్! నా పేరు థ్రెడ్-1 నేను థ్రెడ్! నా పేరు థ్రెడ్-0 నేను థ్రెడ్! నా పేరు థ్రెడ్-3 నేను థ్రెడ్! నా పేరు థ్రెడ్-6 నేను థ్రెడ్! నా పేరు థ్రెడ్-7 నేను థ్రెడ్! నా పేరు థ్రెడ్-4 నేను థ్రెడ్! నా పేరు థ్రెడ్-5 నేను థ్రెడ్! నా పేరు థ్రెడ్-9 నేను థ్రెడ్! నా పేరు థ్రెడ్-8 10 థ్రెడ్లను ( MyFirstThread ఆబ్జెక్ట్లు, ఇది థ్రెడ్ను వారసత్వంగా పొందుతుంది) క్రియేట్ చేద్దాం మరియు ప్రతి వస్తువుపై ప్రారంభ() పద్ధతిని కాల్ చేయడం ద్వారా వాటిని ప్రారంభించండి. ప్రారంభ () పద్ధతిని కాల్ చేసిన తర్వాత , రన్ () పద్ధతిలోని లాజిక్ అమలు చేయబడుతుంది. గమనిక: థ్రెడ్ పేర్లు క్రమంలో లేవు. అవి వరుసగా ఉండకపోవడం విచిత్రం:, థ్రెడ్-1 , థ్రెడ్-2 , మరియు మొదలైనవి? ఇది జరిగినప్పుడు, 'క్రమం' ఆలోచన సరిపోని సమయానికి ఇది ఒక ఉదాహరణ. సమస్య ఏమిటంటే మేము 10 థ్రెడ్లను సృష్టించడానికి మరియు అమలు చేయడానికి మాత్రమే ఆదేశాలను అందించాము. థ్రెడ్ షెడ్యూలర్, ఒక ప్రత్యేక ఆపరేటింగ్ సిస్టమ్ మెకానిజం, వాటి అమలు క్రమాన్ని నిర్ణయిస్తుంది. దీని ఖచ్చితమైన రూపకల్పన మరియు నిర్ణయాత్మక వ్యూహం లోతైన చర్చకు సంబంధించిన అంశాలు, వీటిని మేము ప్రస్తుతం డైవ్ చేయము. గుర్తుంచుకోవలసిన ప్రధాన విషయం ఏమిటంటే, ప్రోగ్రామర్ థ్రెడ్ల అమలు క్రమాన్ని నియంత్రించలేడు. పరిస్థితి యొక్క తీవ్రతను అర్థం చేసుకోవడానికి, పై ఉదాహరణలో ప్రధాన() పద్ధతిని రెండుసార్లు అమలు చేయడానికి ప్రయత్నించండి. రెండవ పరుగులో కన్సోల్ అవుట్పుట్: నేను థ్రెడ్! నా పేరు థ్రెడ్-0 నేను థ్రెడ్! నా పేరు థ్రెడ్-4 నేను థ్రెడ్! నా పేరు థ్రెడ్-3 నేను థ్రెడ్! నా పేరు థ్రెడ్-2 నేను థ్రెడ్! నా పేరు థ్రెడ్-1 నేను థ్రెడ్! నా పేరు థ్రెడ్-5 నేను థ్రెడ్! నా పేరు థ్రెడ్-6 నేను థ్రెడ్! నా పేరు థ్రెడ్-8 నేను థ్రెడ్! నా పేరు థ్రెడ్-9 నేను థ్రెడ్! మూడవ పరుగు నుండి నా పేరు Thread-7 కన్సోల్ అవుట్పుట్: నేను థ్రెడ్! నా పేరు థ్రెడ్-0 నేను థ్రెడ్! నా పేరు థ్రెడ్-3 నేను థ్రెడ్! నా పేరు థ్రెడ్-1 నేను థ్రెడ్! నా పేరు థ్రెడ్-2 నేను థ్రెడ్! నా పేరు థ్రెడ్-6 నేను థ్రెడ్! నా పేరు థ్రెడ్-4 నేను థ్రెడ్! నా పేరు థ్రెడ్-9 నేను థ్రెడ్! నా పేరు థ్రెడ్-5 నేను థ్రెడ్! నా పేరు థ్రెడ్-7 నేను థ్రెడ్! నా పేరు థ్రెడ్-8
మల్టీథ్రెడింగ్ ద్వారా సమస్యలు సృష్టించబడ్డాయి
పుస్తకాలతో మా ఉదాహరణలో, మల్టీథ్రెడింగ్ చాలా ముఖ్యమైన పనులను పరిష్కరిస్తుంది మరియు మా ప్రోగ్రామ్లను వేగవంతం చేయగలదని మీరు చూశారు. తరచుగా చాలా రెట్లు వేగంగా. కానీ మల్టీథ్రెడింగ్ అనేది కష్టమైన అంశంగా పరిగణించబడుతుంది. నిజానికి, సరిగ్గా ఉపయోగించకపోతే, అది వాటిని పరిష్కరించడానికి బదులుగా సమస్యలను సృష్టిస్తుంది. నేను 'సమస్యలను సృష్టిస్తుంది' అని చెప్పినప్పుడు, నా ఉద్దేశ్యం ఏదో నైరూప్య అర్థంలో కాదు. మల్టీథ్రెడింగ్ సృష్టించగల రెండు నిర్దిష్ట సమస్యలు ఉన్నాయి: డెడ్లాక్ మరియు రేస్ పరిస్థితులు. డెడ్లాక్ అనేది ఒకదానికొకటి కలిగి ఉన్న వనరుల కోసం బహుళ థ్రెడ్లు వేచి ఉండే పరిస్థితి, మరియు వాటిలో ఏదీ అమలును కొనసాగించదు. మేము దాని గురించి తదుపరి పాఠాలలో మరింత మాట్లాడుతాము. ప్రస్తుతానికి కింది ఉదాహరణ సరిపోతుంది: థ్రెడ్-1 కొంత ఆబ్జెక్ట్-1తో సంకర్షణ చెందుతుందని మరియు థ్రెడ్-2 ఆబ్జెక్ట్-2తో సంకర్షణ చెందుతుందని ఊహించండి. ఇంకా, ప్రోగ్రామ్ ఇలా వ్రాయబడింది:- థ్రెడ్-1 ఆబ్జెక్ట్-1తో ఇంటరాక్ట్ అవ్వడాన్ని ఆపివేస్తుంది మరియు థ్రెడ్-2 ఆబ్జెక్ట్-2తో ఇంటరాక్ట్ అవ్వడం ఆపి ఆబ్జెక్ట్-1కి మారిన వెంటనే ఆబ్జెక్ట్-2కి మారుతుంది.
- థ్రెడ్-2 ఆబ్జెక్ట్-2తో ఇంటరాక్ట్ అవ్వడాన్ని ఆపివేస్తుంది మరియు థ్రెడ్-1 ఆబ్జెక్ట్-1తో ఇంటరాక్ట్ అవ్వడం ఆపి ఆబ్జెక్ట్-2కి మారిన వెంటనే ఆబ్జెక్ట్-1కి మారుతుంది.
public class MyFirstThread extends Thread {
@Override
public void run() {
System.out.println("Thread executed: " + getName());
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
MyFirstThread thread = new MyFirstThread();
thread.start();
}
}
}
ఆహారాన్ని వండే రోబోట్ను అమలు చేయడానికి ప్రోగ్రామ్ బాధ్యత వహిస్తుందని ఇప్పుడు ఊహించుకోండి! థ్రెడ్-0 ఫ్రిజ్ నుండి గుడ్లను బయటకు తీస్తుంది. థ్రెడ్-1 స్టవ్ ఆన్ చేస్తుంది. థ్రెడ్-2 ఒక పాన్ పొంది స్టవ్ మీద ఉంచుతుంది. థ్రెడ్-3 స్టవ్ వెలిగిస్తుంది. థ్రెడ్ -4 పాన్ లోకి నూనె పోస్తారు. థ్రెడ్ -5 గుడ్లను పగలగొట్టి పాన్లో పోస్తుంది. థ్రెడ్-6 గుడ్డు పెంకులను చెత్త డబ్బాలో విసిరింది. థ్రెడ్-7 వండిన గుడ్లను బర్నర్ నుండి తొలగిస్తుంది. థ్రెడ్-8 వండిన గుడ్లను ఒక ప్లేట్లో ఉంచుతుంది. థ్రెడ్-9 వంటలను కడుగుతుంది. మా ప్రోగ్రామ్ ఫలితాలను చూడండి: Thread అమలు చేయబడింది: Thread-0 Thread అమలు చేయబడింది: Thread-2 Thread అమలు చేయబడింది Thread-1 Thread అమలు చేయబడింది: Thread-4 Thread అమలు చేయబడింది: Thread-9 Thread అమలు చేయబడింది: Thread-5 Thread అమలు చేయబడింది: Thread-8 Thread అమలు చేయబడింది అమలు చేయబడింది: Thread-7 థ్రెడ్ అమలు చేయబడింది: Thread-3 ఇది కామెడీ రొటీనా? :) మరియు అన్ని ఎందుకంటే మా ప్రోగ్రామ్ యొక్క పని థ్రెడ్ల అమలు క్రమంలో ఆధారపడి ఉంటుంది. అవసరమైన క్రమం యొక్క స్వల్పంగా ఉల్లంఘన కారణంగా, మన వంటగది నరకంగా మారుతుంది మరియు పిచ్చి రోబోట్ దాని చుట్టూ ఉన్న ప్రతిదాన్ని నాశనం చేస్తుంది. మల్టీథ్రెడ్ ప్రోగ్రామింగ్లో ఇది కూడా ఒక సాధారణ సమస్య. మీరు దాని గురించి ఒకటి కంటే ఎక్కువసార్లు వింటారు. ఈ పాఠాన్ని ముగించేటప్పుడు, మల్టీథ్రెడింగ్ గురించిన పుస్తకాన్ని నేను సిఫార్సు చేయాలనుకుంటున్నాను. 'జావా కరెన్సీ ఇన్ ప్రాక్టీస్' 2006లో వ్రాయబడింది, కానీ దాని ఔచిత్యాన్ని కోల్పోలేదు. ఇది మల్టీథ్రెడ్ జావా ప్రోగ్రామింగ్కు అంకితం చేయబడింది — ప్రాథమిక అంశాల నుండి అత్యంత సాధారణ తప్పులు మరియు యాంటీప్యాటర్న్ల వరకు. మీరు ఏదో ఒక రోజు మల్టీథ్రెడింగ్ గురువు కావాలని నిర్ణయించుకుంటే, ఈ పుస్తకం తప్పనిసరిగా చదవాలి. తదుపరి పాఠాలలో కలుద్దాం! :)
GO TO FULL VERSION