tag:blogger.com,1999:blog-56593669263897374782024-03-05T11:21:53.683+05:30Word Swattera mindful of it...Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.comBlogger67125tag:blogger.com,1999:blog-5659366926389737478.post-55549282191367918772013-11-29T15:40:00.001+05:302013-11-29T16:23:37.766+05:30Delhi to Chennai: 2nd AC and my earthly burdens<div dir="ltr" style="text-align: left;" trbidi="on">
<b><span style="font-size: x-large;">Note:</span></b><br />
<span style="font-size: large;">At the end of 2011, after 1.5 yrs of stay in Delhi, I moved to Chennai. I realized how much I'm tied to this earthly life.</span><br />
<br />
<b><span style="font-size: x-large;">Disclaimer:</span></b><br />
<span style="font-size: large;">This is gonna b a long rambling so beware. To understand this rambling, you need to know Tamil and little bit Hindi.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">I had to take some heavy luggages with me. A heavy big long trolley and a laptop bag is what I planned. Some books, table fan, ceiling fan, LCD monitor and such stuff had to go inside the trolley. By the time I managed to close half heartedly because it didn't hv place for my Harry Potter books, for the 7yr long standing Philips iron box & one heavy wad of fresh bond paper, i was drenched in sweat in the freezing delhi weather. they had to b abandoned. </span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">i started cursing myself. why do i hv so much dependencies? can't i be simple and light?</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">By the time I brought the trolley two floors down, with my bulging laptop bag on the back, I could feel my insides churning. Had to haul the trolley for 5mins in a dirty narrow street with rubble, iron pipes, and descending a slope with my trolley chasing behind me, I caught the eye of a passing auto driver, who stopped. </span><br />
<br />
<span style="font-size: large;">I announced "new delhi railway station", for which he agreed enthusiastically. </span><br />
<br />
<span style="font-size: large;">"thoda help" i said. </span><br />
<br />
<span style="font-size: large;">he helped to haul the monster inside. </span><br />
<br />
<span style="font-size: large;">he asked "kithna". very strange.... </span><br />
<br />
<span style="font-size: large;">I said "bhaiya dhus kilometernaa, meter nahi hein?"</span><br />
<br />
<span style="font-size: large;">"nahi bhaiya" he said. "pandhra(15) kilometers" he said. </span><br />
<br />
<span style="font-size: large;">"haan haan, bolo kithna" i asked. </span><br />
<br />
<span style="font-size: large;">"heavy luggage na, 150, nahi 140 dedho", he said. </span><br />
<br />
<span style="font-size: large;">idhukkaa ivlo pechu. "teek hai" i said. </span><br />
<br />
<span style="font-size: large;">Happily rode the auto for some time and realized that i couldn't lift both of my hands. They were like let us hang down a bit. That bloody trolley hauling.... </span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Driver started talking. I didn't understand a bit this time, he was looking at me in the mirror, I turned here and there, but still he was looking. Huh, wht the heck, </span><br />
<br />
<span style="font-size: large;">"kiya bhaiya" i asked. </span><br />
<br />
<span style="font-size: large;">he said again and this time i caught the word 'time'. oh he is asking the time. i looked at the watch, 7.15. i know 7 and 15 in hindi. but how to say ezhegaaal (7quarters)? frustrated, I said "7.15" in English. He said ok. Now I got little bolder. </span><br />
<br />
<span style="font-size: large;">I again said "saath(che illa adhu aaaru, thoughts running in me) pandhraaa(15)". He said "teek hai" again politely. </span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">In between I saw lot of airport sign boards. Suddenly doubt. Is he going to railway station or airport?! To make sure, I cleverly presented my information in a question. </span><br />
<br />
<span style="font-size: large;">"bhaiya new-delhi-railway-station-mein-kithnaa-time-ogaiyaa(little stress on the station name)?"</span><br />
<br />
<span style="font-size: large;">ogaiyaavaa aagaiyaavaaa onnum velangaliye paannu nenchikitten. </span><br />
<br />
<span style="font-size: large;">He said "aat baje". "ok ok". I was relieved. </span><br />
<br />
<span style="font-size: large;">"Gaadi kithnaa baje..." something he asked. I thought abt how to say 10.30, then just said "dhus". He said ok. adadaaa 'baje'va uttutome, 'pathu mani - dhus baje' miss pannitome..... </span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Now he stopped at petrol pump and waited in the queue. A couple, in the front auto came out and waited close-by. Then my auto-wala pointed near the pump and said something. Blank again.</span><br />
<br />
<span style="font-size: large;">"kiya bhaiya" I said. He explained again. blank. to be helpful, I said "nikkaal jaayenge?". He said something and pointed ahead. This time I got it. He wants me to exit the auto there not here. I got out near the pump dispenser. He was out and looked at the back seat where my trolley half on seat the rest on front bar behind the driver. he pointed out a scratch on the seat under the trolley. </span><br />
<br />
<span style="font-size: large;">I wanted to say "adhu theru sagadhila pidicha serunnu. mudiyumaa?" After a thought I said "ye paani bhaiya..." and I moved away... He was again complaining and again and again examining.... </span><br />
<br />
<span style="font-size: large;">I went and said "ye paaani wala bhaiyaa paaani wala" pointing at the trolley wheel. And came away.... </span><br />
<br />
<span style="font-size: large;">Finally he left the matter and moved the auto to fill up. On the way again airport sign boards showed... Still nervous abt whether he is going to airport or railway station... Then some metro station names showed up which I knew on the way to the station.</span><br />
<br />
<span style="font-size: large;">He stopped at a back entrance to avoid traffic, but still entrance is close-by. With his help I pulled the trolley down. Paid Rs. 150 and waved at him.</span><br />
<br />
<span style="font-size: large;">Kicked the trolley in its hip to tilt and drag; couldn't tilt it directly that's why. Shortly after, a porter came to company... he offered to help... </span><br />
<br />
<span style="font-size: large;">I smiled and said, "mein platform number dhek rahungaa, board mein..." </span><br />
<br />
<span style="font-size: large;">He askd which platform... I said, "pathaa nahi bhaiyaa, pehli mein board mey dhek karna chaiye(actual word chahiye)..."</span><br />
<br />
<span style="font-size: large;">Wwhich train he asked... Tamil Nadu express I said... He said platform no.3</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">I was still unsure... walked a bit and beckoned him to take the trolley (all this while a heavy load was piggybacking me). He weighed it with hand and said "dho sow rupee(200)". </span><br />
<br />
<span style="font-size: large;">I smiled and said "kiya bhaiya, gaadi charge hein. mera auto charge 140 rupees, pandhra kilometer ki. ek sow teek hai naaa... aur pachaas(50) rupee dhedhen...." </span><br />
<br />
<span style="font-size: large;">He said something like "that is auto, this is my body sir." He went silent... Then said, "teek hai 150 dedho saab....". I was like ok anga poi pesippoam... So I put the monster on his head... followed.... he went and stopped in front of the display board... my train was not listed yet. </span><br />
<br />
<span style="font-size: large;">He said platform theen.. </span><br />
<br />
<span style="font-size: large;">I said "idhar wait karo.." There was a guy standing nearby... He said Tamil Nadu express is not listed. I switched to Tamil, "innum poadaliyaaa, neengalum andha trainaaa?" he was surprised. "ungalukku tamil theriyumaaa...." I was like, "vera...?" Now our porter protested to wait any longer... He asked few of his fellows nearby... They all said platform 3. I protested.... "bhaiya, board mein mera train aatha nahi, idhar wait karo... train number aaathaa nahi naa...". This Tamil fellow (our state brother), "ungalukku hindi theriyumaa(very surprisedly)?", I was thinking "aaathaa'voda sari adhukku mela varaaadhu" and said "ada idhu hindiye illeenga...." </span><br />
<br />
<span style="font-size: large;">Porter said tata and went ahead with my luggage.. I ran after him... he descended in platform 3, I followed... he went to the far end, open platform (i already told him my coach was A1.) so he approximately chose a place and unloaded... I paid him 150 since he said he works with his body... after paying when the onlookers clearly saw 150 being handed over I felt so stupid.... after several mokkais on the phone, I looked around (now sitting on my monster). one Tamil paiyan... first I asked in english abt which train he is waiting for. He said TN express. I switched to Tamil and rambled abt his business in delhi sondha ooor, education, surprisingly he knows Hindi. </span><br />
<br />
<span style="font-size: large;">He got a call. He answered in Hindi and went elaborately fluent in Hindi... 'kacha mucha, mera poora, aacha poachaaa appuram lug thaathaa'nu mudichaan paaaru... adangappaaa, namakku aaathaaa mattum dhaaan varudhu.... ivanukku lug thaaathaaa verikkum varudhe....!?'</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Oru vazhiyaa train just 15 minutesukku munnnaaadi vara, already annan tanku fullu... bag mudgugula yera, trolley'ya odhaichi oru izhu... A1 stopped in front of me... let the crowd crawl in and I followed... narrow entrance... backpack interfering everywhere... had to spill my guts to lift my trolley over those two small steps in the train... now AC car glass door. so narrow.... went backwards to let my backpack then went forward to cling on the trolley handle and dragged sideways(no wheel rolling). first seat is mine... ha... there was a Tamil elderly maami conversing in Tamil with her aaathukaar... ayyar thaathaaa having a cross conversation in impeccable Hindi with a co-passenger. asked maami to move... pushed in my trolley under the seat, it got stuck halfway, more people getting on board were being clogged by me. So, I left the trolley as it is and moved inside where thaatha is hindying... </span><br />
<br />
<span style="font-size: large;">People now getting in & kicking my trolley in the process. thaatha hindyed me abt my seat. I tamiled him and said 46. he hindied again abt my trolley being in the walkway, I tamilled him that once traffic is over I will push it inside. He hindied me that it will not go... I tamilled him that I will make it u just see. I offered maami to take my lower seat and I can go up. she said, the lower seat is hers so no problem. I was own finished, and said oh ok ok. sari sari. appa irungo...</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Unloaded the tank and came back... was trying to climb up. now thaatha hindied me 'aaapkaa seat oooper mein'? I said, enakku hindiyellaam varaaadhu, en seatu 46 mela. thats it. Finally he tamiled me, "oh chari chari". </span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Dinner came @ 140 rupees, I said "no". I had no water and didn't drink water for the last 4 hrs thinking that I can't leave my luggage to go to loo. Both I and thaaatha asked for paaani. Tea came, snacks came, veg biriyaani came(took one), but had to wait for water. In late night trains I had the experience of asking for water and it wud never come. Everything else came by. TTR went by. 11.15pm already. I didnt want to starve. A milk service came. Took 3 cups (Rs.30) and filled my flask. "moonu paaalu namakku... oooooo......". Took the veg biriyaani. drank some milk, it was made from milk powder. suddenly came water.... cursing I took one... no plug point in my seat... so no movie watching... took my mobile... typed all the above with my stylus... my hands were numb again...</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Finally when I came out on the Chennai railway station platform, I could roll my trolley and approached the exit. Phoned my brother to pick me up. Sat at a chair at the entrance of the station looking out for my brother. One Hindi fellow (youth in his teens) (probably working in Chennai) came from outside and took a seat next to me. He had some small dirty pack looked like some tools wrapped in 'koni' or 'saakku pai'. He put it down. His phone rang. He took it and conversed in utterly amazingly fluent Tamil that I was wondering he might be some kind of cross between a north indian & south indian. I was so ashamed for not knowing Hindi. He finished the conversation on the phone. Sat for some time. Then, he turned to me and said 'bhai... ek minute ki.... [please look after my parcel for a minute - in hindi]'. I was like "wow... not only iyar thaathaa, but he also thinks I'm northy". I said okay okay. Then he left. And a fear came to me suggesting that, that gaudy looking parcel might be a bomb and a call he took a while back might be from the bombing master mind. I moved away little bit and watched the parcel.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Then he came back. My brother came. I went home. Then I realized that, Chennai is no longer a Tamil dominated city. Hindi is generally being used everywhere. In 2007, you can't see Hindi speaking people anywhere much in Chennai except for some posh areas. But today, you can't order your breakfast in Tamil in Chennai restaurants. You have to talk in Hindi.</span><br />
<br />
<span style="font-size: large;">Finally I reached my brother's house in Chengalpattu. Next day I went to a close-by fancy store to buy some items. When I approached the counter, that guy started like "Ah bhaiya, kiya chahiye.... bla bla..."</span><br />
<br />
<span style="font-size: large;">அடங்கப்பா, ஹிந்தி என்ன உடாது போல....!! முதல்ல நான் பெரிய மீசை (முடியுமா...!) வெக்கினும்... அப்ப தான் எல்லாரும் என்ன ஒரு தமிழன்னு ஒத்துக்குவாங்க போல...?! </span><br />
<br />
-The End</div>
Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com2tag:blogger.com,1999:blog-5659366926389737478.post-59964308371522595042012-12-31T22:50:00.000+05:302015-01-25T21:48:17.457+05:30திருடன்: அத்தியாயம் 1: எதிர்பாரா விருந்து (Hobbit in Tamil)<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-size: x-small;"><br /></span>
<br />
<h1>
</h1>
<h1>
<span style="font-size: x-small;"><span lang="AR-SA" style="font-family: "Latha","sans-serif";">திருடன்</span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-bidi-language: TA;"><o:p></o:p></span></span></h1>
<div class="MsoNormal">
<span style="font-size: x-small;"><i>[<b>Disclaimer and </b></i><b><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முன்குறிப்பு :</span></i></b><i> This
is not my story. For you to figure out. </i><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறிவியல் அறியப்படாத காலம்</span>; </i><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பூமித்தாய் மிகக் கரடு முரடாக ஆனால்
செம்மையாக இருந்த காலம்</span>; </i><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சில</span><span lang="AR-SA"> </span></i><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஆயிரம்</span><span lang="AR-SA"> </span></i><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வருடங்களுக்கு
முன்னால்</span>, </i><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பூமியின்
மத்திய பிரதேசத்தில் மனிதர்களின் ஆதிக்கம் மிகுந்திருந்தது. அப்போது .... ]</span></i><br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு நில பொந்தில் ஓர்</span><span lang="AR-SA"> </span><b><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன்</span></i></b><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வாழ்ந்து
வந்தான். பொந்துனா</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சேரும்
சகதியும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நீரும்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">புழுவும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பூச்சியும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நாற்றமும் நண்டுகளும் நிறைந்த
அருவருக்கத்தக்க பொந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இல்லீங்க. அதுக்காக</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காய்ந்து உலர்ந்த</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கல்லும் மணலும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கிடக்கும் உட்கார</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வசதி
இல்லாத</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அல்லது
அமர்ந்து சாப்பிட முடியாத பொந்தும் இல்லீங்க: இது ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன் குழி. அப்படீன்னா</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வசதி மிக்க ஒரு சவுகரியமான வசிப்பிடம்
என்று</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அர்த்தம்.</span><br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதற்கு அழகான ஒரு
வட்டக்கதவு இருந்தது. பச்சை நிற வண்ணம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பூசப்பட்ட அந்த கதவின் நடு புள்ளியில்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பளீரிடும் மஞ்சள் நிற
பித்தளை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குமிழ் அல்லது கைப்பிடி காணப்பட்டது. அந்த கதவுக்குப்பின்னால்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வரவேற்பறை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குழாய்
வடிவில் அமைக்கப்பட்டிருந்தது. பார்பதற்கு துளைத்தெடுத்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சுரங்கப்பாதை போன்றிருந்தது</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மிகவும் சௌகரியமான சுரங்கம்</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">புகை தூசி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எதுவும் இல்லாமல்</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அந்த குழாய் வடிவ அறையின் உட்புற
சுவர்கள் மிக</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நேர்த்தியான மரப்பலகைகளால் செய்யப்பட்டிருந்தன</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தரை முழுதும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பளிங்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கற்கள் பதிக்கப்பட்டு</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கால் மிதி கம்பளம்
விரிக்கப்பட்டிருந்தது</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மெருகு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பூசி
மினுக்கும் நாற்காலிகள் ஆங்காங்கே போடப்பட்டிருந்தன. பிறகு ஏகப்பட்ட</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஏகப்பட்ட</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பலப்பல மரக்கொக்கிகள் இருந்தன</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தொப்பிகள் மற்றும் மேலங்கிகள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாட்டுவதற்காக</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த எல்லனுக்கு
விருந்தாளிகள் என்றால் மிகவும் பிரியம். இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சுரங்கப்பாதை(அல்லது வரவேற்பறை!) மேலும்
மேலும் உள்ளே சென்றுகொண்டே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருந்தது</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குன்றின் ஒரே பக்கவாட்டில் செல்லாமல்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இடது வலது என இரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பக்கவாட்டிலும்
வளைந்து பின்னி பாம்புபோல் அமைந்திருந்தது. குன்றின் இரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வெளிப்பக்கங்களிலும் மேலும் பல
வட்டக்கதவுகள் திறந்தன</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஆமாம்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சுற்றுவட்டாரத்தில்
எல்லோரும் இதை மலைக்குன்று என்று தான் அழைத்தார்கள்.</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நமது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வீடு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உலகம்</span>.<br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லனுக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மேல்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாடி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கிடையாது</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அல்லது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லர்களுக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">படி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஏறுவது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பிடிக்காது</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">படுக்கை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறைகள்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குளியலறைகள்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உணவுப்பொருட்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நிறைந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கிடக்கும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உக்கிராண</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறைகள்</span>(<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஏகப்பட்ட</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவை</span>), <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஊக்கபானக்கிடங்குகள்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">துணி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அலமாரிகள்</span>(<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதுவும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அலமாரிகள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முழுக்க</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நிறைந்திருந்தன</span>), <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சமையலறைகள்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உணவருந்தும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உண்டி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறைகள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அனைத்தும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அடுக்கில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காணப்பட்டன</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குழியில்</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதுவும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அனைத்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறைகளும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சுரங்கம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">போன்ற</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாதையின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">புறங்களிலும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அமைந்திருந்தன</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருக்கும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறைகளிளிலேயே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மிகச்சிறந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறைகள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாதையின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இடப்பக்கம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருந்தன</span>. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஏனென்றால்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறைகளில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மட்டும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஜன்னல்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருந்தன</span>. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வட்ட</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வடிவில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உள்வாங்கலாக</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பதிக்கப்பட்ட</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஜன்னல்களிலிருந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வெளியே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உள்ள</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லனின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தோட்டத்தையும்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சரிந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஆற்றங்கரை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வரை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">செல்லும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">புல்மேடுகளையும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காண</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முடியும்</span>.<br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மிகவும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வசதியானவர்</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவருடைய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெயர்</span>
'<b><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்ஸ்</span></i></b>'.
[<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இனிமேல்</span> '<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவர்</span>' <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்று</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மரியாதையாகத்தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அழைக்கபோகிறோம்</span>]
. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்ஸ்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவர்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குடும்பப்பெயர்</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்ஸ்கள்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தலைமுறை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தலைமுறையாக</span> (<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எத்தனை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தலைமுறை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்று</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">யாருக்கும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தெரியாது</span>), <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மலைக்குன்று</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பகுதியில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வாழ்ந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வருகிறார்கள்</span>. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மக்களிடையே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்ஸ்களுக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மிக்க</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மதிப்பும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மரியாதையும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருந்தது</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வசதி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">படைத்தவர்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதற்காக</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மட்டும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அல்ல</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்ஸ்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வித</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சாகசங்களிலும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஈடுபடமாட்டார்கள்</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அல்லது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வழக்கத்துக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாறாக</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எதையும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">செய்ய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாட்டார்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதற்காகவும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மதிப்பும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மரியாதையும்</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்ஸ்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இன்னதொரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கேள்விக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்ன</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பதில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சொல்வான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவனிடம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கேட்காமல்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">யார்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வேண்டுமானாலும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சொல்லி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விடலாம்</span>.<br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்தக்கதையில்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்ஸ்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குடும்பத்தில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எப்படி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பிரமிப்பான</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சாகசங்களில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஈடுபடப்போகிறான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதையும்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வழக்கத்திற்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாறான</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காரியங்களை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">செய்யப்போகிறான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதையும்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எதிர்பாராத</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விஷயங்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வாயிலிருந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வரப்போகிறது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதையும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பார்க்கத்தானே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">போகிறீர்கள்</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இதனால்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவருடைய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மரியாதை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அக்கம்பக்கத்தில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குறையப்போகிறது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்றாலும்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவர்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நிறைய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">லாபம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அடையப்போகிறார்</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முடிவில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எதையாவது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சம்பாதிக்கப்போகிராரா</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நீங்களே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாருங்களேன்</span>.<br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நாம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பேசிக்கொண்டிருக்கும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லரின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அம்மா</span>,
(<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கொஞ்சம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மரியாதை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குறைவாக</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருக்கிறது</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதான்</span>),
.......... <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஆமாம்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்றால்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்ன</span>?<br />
<br />
<span lang="AR-SA" style="font-family: Latha, sans-serif;">எல்லன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: Latha, sans-serif;">அறிமுகம்</span><br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்தக்காலத்தில்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லர்களுக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறிமுகம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒன்று</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தேவைப்படுகிறது</span>!
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்ன</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">செய்வது</span>?
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லர்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எண்ணிக்கையில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சொற்பமாகி</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பார்பதற்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அரிதாகி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விட்டார்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இப்போது</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மேலும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவர்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உயர</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மனிதர்களிடம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவ்வளவாகப்பழகுவதில்லை</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உயர</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மனிதர்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்று</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவர்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குறிப்பிடுவது</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நம்மை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தான்</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லர்கள்</span><span lang="AR-SA"> </span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">உ</span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ருவில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மிகவும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சிறிய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மனிதர்கள்</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உயரத்தில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாதி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உயரம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவர்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வளர்வார்கள்</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உருவிலும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உயரத்திலும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தாடியுடன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கூடிய</span><span lang="AR-SA"> </span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-bidi-theme-font: minor-bidi; mso-hansi-font-family: "Times New Roman";">கற்</span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குள்ளர்களை</span>(dwarf) <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விட</span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";"> உயரம்</span><span lang="TA"> </span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-bidi-theme-font: minor-bidi; mso-hansi-font-family: "Times New Roman";">குறைந்தவர்கள் </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லர்கள்</span>. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லர்களுக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தாடி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கிடையாது</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவர்களிடம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மந்திர</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சக்தியும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கூட</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இல்லை</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஆனால்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லர்களுக்கே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உரிய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குணம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உண்டு</span> - <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உங்களையும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்னையும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">போன்ற</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெரிய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உயர</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மனிதர்கள்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாங்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாங்கென்று</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நடந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வந்தால்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மைல்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தூரத்தில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வரும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">யானையின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சத்தம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">போல</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கேட்க்கும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவர்களுக்கு</span>. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பிறகென்ன</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நாம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வருவதற்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முன்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சத்தமில்லாமல்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கண்ணிமைக்கும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நேரத்தில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மறைந்துவிடுவார்கள்</span>.<br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவர்கள்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கண்ணைப்பறிக்கும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வண்ணத்தில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உடை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அணிவார்கள்</span>(<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெரும்பாலும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பச்சை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மற்றும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மஞ்சள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நிறத்தில்</span>); <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காலணி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எதுவும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அணிய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாட்டார்கள்</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஏனென்றால்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இயற்கையாகவே</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவர்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாதத்தில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கடினமான</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தோல்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வளரும்</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சமயத்தில்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அடர்ந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">செம்பட்டை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நிற</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முடியும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவர்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாதத்தில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வளரும்</span>. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவர்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தலை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முடியும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாதிரி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருக்கும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சுருள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சுருளாக</span>. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சிவந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நீளமான</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">திறம்மிக்க</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விரல்களைக்கொண்டவர்கள்</span>. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அழகான</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முகம்</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கணீரென</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சிரிப்பு</span>(<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தொண்டையிலிருந்து</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதுவும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இரவு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நேர</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உணவுக்குப்பிறகு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சிரிப்பு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதிகம்</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கிடைத்தால்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இரவில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இ</span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">ரண்டு தடவை</span><span lang="TA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சாப்பிடுவார்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தினமும்</span>).<br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இப்போதைக்கு</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அளவு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அறிமுகம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">போதும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்று</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நினைக்கிறேன்</span>. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஆங்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முன்னாடி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சொல்லிக்கொண்டிருந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாதிரி</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நம்ம</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லர்</span>
'<b><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பில்போ</span><span lang="AR-SA"> </span></i></b><b><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்ஸ்</span></i></b>'<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஓட</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அம்மா</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பேரு</span> '<b><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெல்லடோனா</span><span lang="AR-SA"> </span></i></b><b><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span></i></b>'!!! (<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முடியல</span>?!?). [<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மன்னிக்கவும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாதிரி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெயர்களெல்லாம்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பழங்கால</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">புவி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மத்தியப்பிரதேசத்தில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அப்போது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வழக்கத்திலிருந்தது</span>].
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெண்</span><span lang="AR-SA"> </span><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லி</span></i>
(<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெண்பால்</span>)
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெல்லடோனா</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பிரசித்திபெற்ற</span><span lang="AR-SA"> </span><b><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span></b><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பவருக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பிறந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மூன்று</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மிகச்சிறந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெண்களில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒருவர்</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பில்போவின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மலைக்குன்றுக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அருகில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஓடும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஆற்றுக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெயர்</span><span lang="AR-SA"> </span><b><i><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நீராறு</span></i></b>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஆற்றைத்தாண்டி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வாழும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லர்க</span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">ளு</span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">க்கெல்லாம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஆஸ்தான</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தலைவராக</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருந்தவர்தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெரியவர்</span>. (<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதாவது</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பில்போவின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தாத்தா</span>). <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பரம்பரையில்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பலகாலத்துக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முன்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">யாரோ</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குறும்பு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தேவதையை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கல்யாணம்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">செய்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கொண்டார்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்று</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஊரில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உள்ள</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மற்ற</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குடும்பத்தினர்</span><span lang="AR-SA">
</span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">புரளி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பேசிக்கொள்வார்கள்.</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உண்மை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இல்லை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்றாலும்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">புரளிக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காரணம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உண்டு</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவ்வப்பொழுது</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பரம்பரையில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வரும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">யாராவது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒருத்தர்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">திடீரென</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒருநாள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">யாருக்கும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தெரியாமல்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மறைந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விடுவார்</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சாகச</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பயணம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">செல்ல</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குடும்பத்தினர்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இதை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எப்படியாவது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மூடி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மறைத்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விடுவர்</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதனால்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">செல்வந்தர்களான</span><span lang="AR-SA">
</span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குடும்பத்தை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விட</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்ஸ்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குடும்பத்தினர்க்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மக்களிடையே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">செல்வாக்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதிகம்</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குடும்பத்தினரும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெரும்பாலும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பணம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">படைத்தவர்களாகவே</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருந்தார்கள்</span>.<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எப்படி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருந்தாலும்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெல்லடோனா</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாதிரி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சாகசத்திலும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஈடுபடவில்லை</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பங்கோ</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்சை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கல்யாணம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கட்டிக்கொண்ட</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பிறகும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கூட</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒ</span>! <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-bidi-theme-font: minor-bidi; mso-hansi-font-family: "Times New Roman";">‘</span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பங்கோ</span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">’</span><span lang="TA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பில்போவோட</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அப்பா</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவர்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வசதி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மிக்க</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குழியை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மனைவிக்காக</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கட்டினார்</span>[<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாதி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பணம்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மனைவியிடம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வந்தது</span> ;-)]. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவர்கள்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கடைசி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காலம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வரை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இங்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தான்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வாழ்தார்கள்</span>.<br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பெல்லடோனாவின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மகன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பில்போ</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பார்ப்பதற்கும்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பழகுவதற்கும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அப்பாவை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அச்சு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எடுத்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மாதிரி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருந்தாலும்</span>
(<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதாவது</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கம்பீரத்திலும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சௌகரிய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பிரியத்திலும்</span>) , <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஏதோ</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ரகசிய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">டூக்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பரம்பரை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குணம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அவரின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பவ்யத்தில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருந்தது</span>. <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சந்தர்ப்பம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கிடைத்தால்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வெளிவர</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காத்துக்கொண்டிருந்தது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அது</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பில்போ</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பாகின்ஸ்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வளர்ந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஐம்பது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வயதை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தாண்டி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விட்டாலும்</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சந்தர்ப்பம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வரவில்லை</span>.
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பில்போ</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அப்பா</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கட்டிய</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லன்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குழியான</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மலைக்குன்றில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மிகவும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சௌகரியமாக</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வாழ்ந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வந்தார்</span>.<br />
<br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உலகம் அமைதி கொண்டு</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பச்சை பசுமை மிகுந்து</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லர்கள்
பல்கிப்பெருகி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வசதியாக வாழ்ந்து வந்த அந்த காலத்தில்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு நாள் காலை -- பில்போ பாகின்ஸ்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காலை
உணவருந்திவிட்டு தன் வீட்டு வாசலில் நின்று கொண்டிருந்தார். முடி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அடர்ந்து
வளர்ந்திருந்த பாதம் வரை நீண்டிருந்த நீளமான பெரிய அந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மரக்குழாயில் புகைப்பிடித்துக்
கொண்டிருந்தார்</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அப்போது
தான் காண்டாளர்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வந்து சேர்ந்தார்.</span> <br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காண்டாளர்!
காண்டாளரைப் பற்றி எனக்குத் தெரிந்தது மிகவும் சொற்பம் தான்.</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எனக்கு
தெரிந்ததில் கால்வாசி உங்களுக்கு தெரிந்திருந்தால் கூட</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உடனே ஒரு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அற்புத கதை கேட்க தயாராகிவிடுவீர்கள்.
அவர் செல்லும் இடமெல்லாம்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நம்ப</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">முடியாத</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விசித்திரமான</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பயமுறுத்தும்
சாகசங்களும் கதைகளும் வெளிப்படும்.</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பல காலமாக இந்த மலைக்குன்றின் வழியாக
அவர் வரவில்லை. அவர் நண்பர் அதாவது</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நம் டூக் பெரியவர் இறந்ததற்குப் பிறகு
அவர் இங்கு வரவேயில்லை.</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சொல்லப்போனால் இங்கு வசிக்கும்
எல்லர்களுக்கு அவர் எப்படி இருப்பார்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்பதே மறந்து விட்டது. அவர்கள் எல்லச்
சிறுவர்களாகவும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லிச்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சிறுமிகளாகவும்
இருந்த காலத்தில் காண்டாளர் தன் சொந்த பணி நிமித்தமாக இந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குன்று
பகுதிக்கும்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நீரார்ற்றுக்கு
அப்பால்பட்ட பகுதிக்கும் வந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">போனதுண்டு. அப்பாவி பில்போவிற்கு இந்த
காலை நேரத்தில் தெரிந்ததெல்லாம்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கைத்தடியுடன் வரும் ஒரு வயதான உயர மனிதன்தான். கைத்தடியுடன்
வரும்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வயதானவர்
என்றால்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கூண்
விழுந்த முதியவர் அல்ல</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இவர்
கம்பீரமாக நிமிர்ந்து</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நடந்து வரும் பெரியவர்</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கையில் ஒரு கைதடியை ஏந்தி வருபவர்</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உயரமான புனல்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">போன்ற
நீல தொப்பி அணிந்திருந்த அவர்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பழுப்பு
நிறத்தில் ஆளுயர மேலங்கி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அணிந்திருந்தார்</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வெள்ளி நிறத்தில் ஒரு சால்வை அவர்
கழுத்தை</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">சுற்றியிருந்தது</span>; <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அதன் மேலே வெள்ளை நிற தாடி நீண்டு வளர்ந்து அவர்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இடுப்புக்கு
கீழே சென்றது. காலில் பெரிய கரும்நிற பூட்ஸ் அணிந்திருந்தார்.</span> <br />
<br />
"<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குட் மார்னிங்!"
என்று அழுத்தமாக கர்ஜித்தார் பில்போ. ஆனால் காண்டாலரின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கண்கள்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">தொப்பியின் விளிம்பு வரை நீண்டிருக்கும்
அவரின் அடர்ந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">புருவத்திற்கு பின்னாலிருந்து பில்போவை
நோக்கின.</span> <br />
<br />
"<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்ன சொல்கிறீர்கள்</span>?
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நீங்கள் எனக்கு இது
ஒரு நல்ல காலைப்பொழுதாக</span> <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இருக்குமென்று
சொல்கிறீர்களா</span>? <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அல்லது</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எனக்கு வேண்டுமோ வேண்டாமோ</span>,
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஆனால்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இது
ஒரு நல்ல காலைப்பொழுது என்கிறீர்களா</span>? <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அல்லது</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உங்களுக்கு
இது ஒரு நல்ல</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">காலைப்பொழுது என்கிறீர்களா</span>? <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அல்லது</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லாரும் நலமாக இருக்க முயற்சி</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">செய்யவேண்டிய
காலைப்பொழுது என்கிறீர்களா</span>?"<br />
<br />
"<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லாவற்றையும் தான்
சொன்னேன்" என்றார் பில்போ. "அது போக</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வீட்டின்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வெளியே இந்த தரமான எல்லர் புகையிலையை
குழலில் போட்டு</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">புகைபிடிக்க
உகந்த</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒரு
அருமையான காலை நேரம் கூட! உங்களிடம் புகை பிடிக்கும் குழல் இருந்தால்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நான் நிரப்பித் தருகிறேன்</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">வந்து உட்காருங்கள். இன்று முழுக்க
நேரம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">உள்ளது</span>;
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எந்த அவசரமும் இல்லை.
பிறகு</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">பில்போ
தன் வாசலில் உள்ள இருக்கையில்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">அமர்ந்தார்.</span> <br />
<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கால்மேல் கால்
போட்டுக்கொண்டார். பிறகு அழகான ஒரு பழுப்பு நிற புகை வளையம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">ஒன்று
அவர் புகைகுழலிளிருந்து வெளிவந்து</span>, <span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">மேலே சென்று அலையாமல் கலையாமல்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">குன்றின் மேலே சென்று மிதக்க
ஆரம்பித்தது.</span> <br />
"<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">என்ன அருமை! என்ன
நேர்த்தி!" என்றார் காண்டாளர். "ஆனால் புகைவளையம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">விட்டு
விளையாட இன்று எனக்கு நேரமில்லை. நான் ஒரு சாகசப் பயணத்திற்கு</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">திட்டமிட்டுக்கொண்டிருக்கிறேன்.
அதற்க்கு ஓர் ஆள் தேவைப்படுகிறது. ஆனால்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">இங்கு யாரும் கிடைக்கவில்லை.</span> <br />
<br />
<<<span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">கண்டிப்பாக! யாரும்
கிடைக்க மாட்டார்கள். அதுவும் இந்த ஊரில்.</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">நாங்களெல்லாம் சாதாரணமாகவும்
அமைதியாகவும் வாழ விரும்புபவர்கள். சாகசம்</span><span lang="AR-SA"> </span><span lang="AR-SA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-hansi-font-family: "Times New Roman";">எல்லாம் எங்களுக்கு பயன்படாது!</span><span lang="AR-SA"> </span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">கொடூரமான</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">கேவலமான</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">கஷ்டத்தை கொடுக்கும்</span>,
<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">அசௌகரியமான காரியங்கள் அவை! இரவு உணவிற்கு உன்னை தாமதமாக்கிவிடும்! இதிலே என்ன
தான் இருக்கிறதோ எனக்குத் தெரியவில்லை...</span>>> <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">என்றார் மிஸ்டர் பில்போ
பாகின்ஸ். தன் மேலங்கியின் பைக்குள்ளே ஒரு கையை விட்டுக்கொண்டே</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">இன்னொரு புகை வளையத்தை
(முன்னைவிட பெரியது) விட்டுவிட்டு</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">அன்று வந்திருந்த தபால்களை எடுத்து படிக்க ஆரம்பித்தார். எதிரே
நிற்கும் அந்த கிழவரை கண்டுகொள்ளாமல்</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">அங்கு யாருமே இல்லை என்பது போல் படித்துக்கொண்டிருந்தார்.
இந்தக் கிழவரை பில்போவிற்கு ஏனோ பிடிக்கவில்லை. அவர் அங்கிருந்து போய் விடுவார் என்று
காத்திருந்தார். ஆனால் அக்கிழவர் இம்மி அளவுகூட நகரவில்லை. தன் கைதடியை ஊன்றி நின்றுகொண்டு
பில்போவையே வெறித்து பார்த்துகொண்டிருந்தார். பில்போவிற்கு அந்த நிசப்தம் தாங்கவில்லை.
</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;">"<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">குட் மார்னிங்!" என்றார் பில்போ கடைசியாக. "எங்களுக்கு
சாகசம் எதுவும் தேவையில்லை! நன்றி! நீங்கள்
இந்த குன்றிற்கு மேல் பகுதியிலோ அல்லது நீராற்றைத் தாண்டியோ போய்க் கேளுங்கள்."
என்று பேச்சுவார்த்தைக்கு முற்றுபுள்ளி வைப்பது போல் சொல்லி முடித்தார். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;">"<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">நீங்கள் </span>'<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">குட் மார்னிங்கை</span>' <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">எந்தெந்த விஷயதிர்க்கெல்லாம் பயன்படுத்துவீர்கள்</span>?"
<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">என்றார் காண்டாளர். "இப்பொழுது நான் இங்கிருந்து போய் விடவேண்டும்</span>;
<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">அதுதானே தேவை உங்களுக்கு</span>?"<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;">"<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">ஐயோ! அப்படியில்லை</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">அப்படியில்லை பெரியவரே! ஆங்</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">உங்கள் பெயர் என்னவென்று
எனக்குத் தெரியவில்லையே</span>?"<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;">"<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">ஆமாம்</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">ஆமாம் அன்பரே - ஆனால் எனக்கு உங்கள் பெயர் பில்போ பாகின்ஸ் என்று
தெரியும். அப்புறம்</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">உங்களுக்கும் என் பெயர் தெரியும். ஆனால் அந்த பெயருக்கு சொந்தக்காரன்
நான் தான் என்பது உங்கள் நினைவுக்கு வரவில்லை. நான்தான் </span>'<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">காண்டாளர்</span>'.
<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">காண்டாளர் தான் நான்! என்ன கொடுமை எல்லரே</span>?! <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">பெல்லடோனா டூக்கின்
மகன் எனக்கு</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">வீதியில் பொத்தான் விற்கும் பித்தனுக்கு </span>'<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">குட் மார்னிங்</span>'
<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-hansi-font-family: "Times New Roman";">சொல்வது போல சொல்வார் என்பதை பார்க்க நான் உயிரோடு இருக்கிறேன்!"</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;">"<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">காண்டாளர்</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">காண்டாளர்! நல்ல கொடுமை! மன்னிக்கவும்</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">மன்னிக்கவும். எங்கள் ‘டூக்’ பெரியவருக்கு
ஒரு ஜோடி மந்திர வைரங்களை பரிசாகக் கொடுத்த</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பல நாடுகள்</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பிரதேசங்கள் சென்று திரியும் அந்த சக்திவாய்ந்த
மந்திர வாதியல்லவா நீங்கள்! அந்த வைர உருண்டைகள் கூட ஓடி ஒட்டிக்கொண்டு </span>'<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பிரிந்து வா!</span>' <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">என்று கட்டளையிடும் வரை வராமல் அடம்
பிடிதனவே! விருந்து நிகழ்ச்சிகளில் அருமை அருமையாக
கதை கூட சொல்வீர்களே.</span><span lang="TA"> </span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“</span><o:p></o:p></span></div>
<div style="border-bottom: solid windowtext 1.0pt; border: none; mso-border-bottom-alt: solid windowtext .75pt; mso-element: para-border-div; padding: 0in 0in 1.0pt 0in;">
<div class="MsoNormal" style="border: none; mso-border-bottom-alt: solid windowtext .75pt; mso-padding-alt: 0in 0in 1.0pt 0in; padding: 0in;">
<span style="font-size: x-small;"><br /></span></div>
</div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“டிராகன் கதைகள்; கோபுளின்(</span>goblin – <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">நீண்ட காதுடைய மந்திர சக்தி படைத்த
பெரிய கண் கொண்ட சிதைந்த மனித உடல் போன்ற உருவம் கொண்ட அறிவு குன்றிய ஜந்துகள்</span>)<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";"> கதைகள்; அரக்கர்கள் பற்றிய கதைகள்; இளவரசிகளை
காப்பாற்றும் கதைகள்; கணவனை இழந்த பெண்களின் மகன்களுக்கு அடிக்கும் திடீர் யோகங்கள்,
இப்படி பல வித கதைகள் சொல்வீர்களே! எங்கும் காணாத கண்ணை கவரும் வண்ண வண்ண
விசித்திர வான வேடிக்கைகளும் பட்டாசுகளும் கூட போட்டுக் காட்டுவீர்களே! எனக்கு
ஞாபகம் இருக்கிறது. ‘டூக்’ தாத்தாவின் கோடை கால விழா கொண்டாட்டத்தில் தானே இந்த
வான வேடிக்கைகள் செய்வீர்கள்? அற்புதமான வாணவெடிகள்; ராட்சத லில்லி பூ மாதிரி
வானத்தில் தோன்றி சாயுங்காலம் வரை மிதந்து கொண்டிருக்குமே; சில வான வெடிகள்
வெடித்து, பெரிய தாமரை பூவையும், தாழம்பூவையும், மல்லிகை செண்டுகளையும் வானத்தில்
உலவ விடுமே. மிகவும் அருமை உங்கள் வாணவெடிகள்!”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">என்ன உப்பு சப்பு இல்லாமல் பேசும்
பாகின்ஸ், திடீர் என்று கவிதை போல பேசுகிறார் என்று பார்க்கிரீர்களா? அது ஒன்றும்
இல்லை, பூக்கள் என்றால் அவருக்கு பிரியம், அதான்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“ஆஹா! பைத்தியக்காரத்தனமாக, சாகச
பயணம் போக வேண்டும் என்று, திடீரென்று ஆண் பெண் இளவட்டங்கள் காணாமல் போய்விடுமே!
அதற்க்கு காரணமான ‘காண்டாளர்’ தானே நீங்கள்? மரம் ஏறுவது, வெண் தேவர்களை(</span>elf<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">)</span><span lang="TA"> </span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">சந்திப்பது, கப்பலில் பயணம் செய்வது, கண் கானா தேச கடற்கரைக்கு செல்வது; அப்பப்பா!
வாழ்க்கை எப்படி களைகட்டி........ அதாவது, நிம்மதியின்றி போனது. அமைதியான இந்த
எல்லர் கிராமத்தில் நிறைய குழப்பத்தை உண்டு பண்ணுவீர்கள் அப்போது, இல்லையா? தாங்கள்
மன்னிக்க வேண்டும், நீங்கள் இன்னும் இது மாதிரி சில்மிஷ வேளைகளில்
ஈடுபட்டுக்கொண்டிருப்பீர்கள் என்று நான் எதிர் பார்க்கவில்லை.”<o:p></o:p></span></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“வேறெங்கு போவது நான்?” என்றார்
அந்த மந்திரவாதி. “எது எப்படி போனாலும், என்னை பற்றி கொஞ்சம் ஞாபகம் இருக்கே.
ரொம்ப சந்தோஷம். என்னோட வாணவெடிகள பத்தி ரொம்ப புகழ்ந்து வேற பேசிட்டீங்க. அதனால
இந்த நாட்டு மேல இன்னும் கொஞ்ச நம்பிக்கை இருக்கு எனக்கு. சரி. உங்க ‘டூக்’ தாத்தாவுக்காகவும்,
உங்கம்மா ‘பெல்லடோணா” பேருக்காகவும், நீங்கள் கேட்டதை நான் கட்டாயம் கொடுக்கிறேன்.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“மன்னிக்க வேண்டும். நான்
உங்களிடம் எதுவும் கேட்கவில்லையே?”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“கண்டிப்பாக கேட்டீர்கள்! இப்போ
இரண்டாவது முறை வேறு கேட்டீர்கள். என்னுடைய மன்னிப்பு. கொடுத்து விடுகிறேன்.
மன்னித்து விடுகிறேன். அது போக, உங்களை இந்த சாகச பயணத்திலும்
சேர்த்துக்கொள்கிறேன். எனக்கு சுவாரசியமாக இருக்கும். உங்களுக்கும் பயனுள்ளதாக இருக்கும்.
லாபகரமாகவும் இருக்கும். நம்பவே முடியாததாக இருக்கும். ஆனால் சீக்கிரம் நம்பி
விடுவீர்கள்.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“மிக்க வருத்தங்களுடன் உங்கள்
அழைப்பை நான் மறுக்க வேண்டியிருக்கிறது. அழைப்புக்கு நன்றி. என்னால் முடியாது.
கண்டிப்பாக இன்றைக்கு இல்லை. குட் மார்னிங். ஆனால் நீங்கள் கண்டிப்பாக தேநீர்
அருந்த என் வீட்டிற்கு வர வேண்டும். எப்பொழுது வேண்டுமானாலும். ஏன் நீங்கள்
நாளைக்கு வரக்கூடாது? நாளைக்கு வாருங்கள். வணக்கம்! வருகிறேன்!”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">அத்துடன், எல்லர், திரும்பி,
சரக்கென்று தன் பச்சை நிற வட்ட கதவுக்குள் புகுந்து விட்டார். மரியாதை குறைவாக
நடக்க கூடாது என்று, சிறிது இடைவெளி விட்டு, பின்னர் கதவை சாத்திக்கொண்டார். மந்திரக்காரர்கள்
மீது எல்லாருக்கும் சிறிது பயம் தானே.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“எதற்காக நான் அவரை தேநீர்
விருந்துக்கு அழைத்தேன்? அட கொடுமையே!” என்று தனக்கு தானே பேசிக்கொண்டு சரக்கு
அறைக்கு(</span>pantry<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">) சென்றார் நம் பாகின்ஸ்.<o:p></o:p></span></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">கொஞ்ச நேரத்திற்கு முன்பு தான்
காலை உணவு அருந்தியிருந்தார். ஆனாலும் தன் பயம் தெளிய, ஒன்றிரண்டு ‘கேக்’கும், அப்புறம்
ஏதாவது பானம் அருந்தினாலும் நன்றாக இருக்கும் என்று உள்ளே சென்றார்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">காண்டாளர் இன்னும் கதவுக்கு வெளியே
தான் நின்றுகொண்டிருந்தார். அமைதியாக கதவையே பார்த்து சிரித்துக்கொண்டிருந்தார்
வெகு நேரத்திற்கு.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பிறகு காண்டாளர் கதவு அருகில்
வந்து, தனது கைத்தடியின் கூறிய நுனியால், எல்லரின் அந்த அழகான வட்ட வடிவ பச்சை
வர்ண வீட்டுக்கதவில் விசித்திர அடையாளம் ஒன்று வரைந்தார். பிறகு அவ்விடத்தைவிட்டு
கிளம்பினார். அதே சமயத்தில், தன் இரண்டாவது ‘கேக்’கை முடித்துக்கொண்டிருந்த நம்
பில்போ அவர்கள், திறமையாக, ஒரு சாகச பயணத்தில் இருந்து தப்பி விட்டோம் என்று
மகிழ்ந்து கொண்டிருந்தார்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">அடுத்த நாள் அவர் காண்டாளரைப்பற்றி
முற்றும் மறந்து விட்டார். வழக்கமாக, அவர் தன் காலண்டரில் “புதன் – காண்டாளர்”
என்று குறித்து வைத்திருந்தால் அல்லவா அவருக்கு நினைவிருக்கும். நேற்று அவர்
இருந்த பதற்றத்தில் இதையெல்லாம் மறந்து விட்டார். தேநீர் வேலை நேரத்திருக்கு சற்று
முன், அவர் வாசல் அழைப்பு மணி ‘டடாங்’ என்று ஒலித்த போது தான் அவருக்கு
காண்டாளரைப் பற்றி நினைவு வந்தது. அவசரமாக ஓடி, அடுப்பில் தேநீர் கொதி கலனை
வைத்தார். பின், புதியதாக ஒரு தேநீர் கோப்பு (</span>cup<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">) மற்றும் வட்டு தட்டையும்(</span>saucer<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">)</span>, <span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">ஒன்றிரண்டு ‘கேக்’குகளையும்(இனிப்பு
ரொட்டி) வெளியில் எடுத்து வைத்துவிட்டு கதவை திறக்க ஓடினார்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">கதவை திறந்து கொண்டே, “தாமதத்திற்கு
மன்னிக்கவும்” என்று சொல்ல வாயெடுத்த அவர், வாசலில் நிற்பது காண்டாளர் இல்லை என்று
தெரிந்ததும் வாயை மூடிக்கொண்டார். அங்கே நின்றிருந்தது ஒரு கற்குள்ளன்(</span>dwarf<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">).</span><span lang="TA"> </span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">அவன் தன் நீல நிற தாடியை இழுத்து, தன் தங்க இடுப்பு
பெல்ட்டுக்குள் செருகியிருந்தான். அவன் போட்டிருந்த கரும் பச்சை முக்காட்டின்
உள்ளே இருந்து பளீரென தெரிந்தன அவன் கண்கள். </span></span><br />
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";"><br /></span>
</span><br />
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">கதவு திறந்த வேகத்தில்,
அழைக்கப்பட்ட விருந்தாளியைப் போல உள்ளே வந்துவிட்டான் அந்த கற்குள்ளன். முக்காடு
பொருத்திய அவன் மேலங்கியை, அருகில் இருந்த பல மர ஆப்புகளில் ஒன்றில் மாட்டிவிட்டு,
குனிந்து வணங்கி “நான் <b>துவாளின்</b>, உங்கள் சேவைக்காக!” என்று சொன்னான்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">அதிர்ச்சியிலிருந்த எல்லர், என்ன
ஏதென்று கூட கேட்காமல் “நான் பில்போ பாகின்ஸ், உங்கள் சேவைக்காக!” என்றார். பிறகு
ஒரே அமைதி. இருவரும் பேசவில்லை. இந்த நிசப்தம் தாங்க முடியாமல், பில்போ “இப்பொழுது
தான் நான் தேநீர் அருந்தலாம் என்று இருந்தேன். ஏன் நீங்கள் வந்து கொஞ்சம் அருந்தக்
கூடாது” என்று கொஞ்சம் விறைப்பாகவே சொன்னாலும், அன்போடு அழைத்தார் பில்போ. சொல்லாமல்
கொள்ளாமல் திடீரென்று ஒரு கற்குள்ளன் உங்கள் வரவேற்பறையில் வந்து, தன் பொருட்களை
தொங்க விட்டால், என்ன தான் செய்வீர்கள் நீங்கள்?</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">அவர்கள் மேஜைக்கு சென்று கொஞ்ச
நேரம் தான் ஆகியிருந்தது. சொல்லப் போனால் இன்னும் மூன்றாவது ‘கேக்’கை கூட
ஆரம்பிக்கவில்லை. முன்பைவிட சத்தமாக வந்தது அழைப்பு மணி ஓசை மறுபடியும். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“ஒரு நிமிடம் இருங்கள்“ என்று
சொல்லிவிட்டு கதவைத் திறக்க சென்றார் நம் எல்லர்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“ஒரு வழியாக வந்துவிட்டீர்களா?” என்று
காண்டாளரிடம் கேட்க தயாராய் இருந்தார் பில்போ. ஆனால் வந்தது காண்டாளர் இல்லை. வாசற்படியில்
நின்றது ஒரு வினோதமான வயதான வெள்ளைத் தாடி கொண்ட, ரத்த சிவப்பு நிற முக்காடு
போட்டிருந்த ஒரு கற்குள்ளன். இந்த கற்குள்ளனும், கதவு திறந்த வேகத்தில், ஏதோ,
எதிர்பார்க்கப்பட்ட விருந்தாளியைப் போல உள்ளே எம்பிக் குதித்தான்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">துவாளினுடைய பச்சை முக்காடு தொங்கிக்கொண்டிருப்பதைப்
பார்த்த இந்த குள்ளன் “ஒ அவர்கள் வர ஆரம்பித்துவிட்டார்கள் போலிருக்கிறதே” என்று
சொல்லிக்கொண்டே, தன்னுடைய சிவப்பு முக்காட்டை அதன் பக்கத்தில் மாட்டிவிட்டு, தன்னுடைய
மார்பில் கை வைத்து “நான் <b>பாளின்</b> உங்கள் சேவைக்காக!” என்று சொன்னான். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“நன்றி!” என்று சொன்னார் பில்போ
மூச்சிரைப்புடன். இது சரியான பதில் இல்லை தான். ஆனால், இவர்களின் வருகையால்
பதற்றம் அதிகமாகியிருந்தது பில்போவுக்கு. </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">விருந்தாளிகள் என்றால்
பில்போவுக்குப் பிடிக்கும். ஆனால் அவர்கள் வருகை பற்றி அவருக்கு முன்னமே தெரிந்திருக்க
வேண்டும், அத்தோடு அவர்களைத் தானே அழைத்திருக்க வேண்டும் என்று எதிர் பார்ப்பார்
பில்போ. </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">திடீர் என்று அவருக்கு ஒரு பயம்
தோன்றியது. கேக்குகள் காலியாகப்போகின்றனவே என்று. அத்தோடு, வீட்டுக்கு
வந்தவர்களுக்கு நல்ல உபசரணை செய்வது தான் ஒரு எல்லனின் நல்ல பழக்கம். எவ்வளவு
அசௌகரியமாக இருந்தாலும், விருந்தோம்பலில் தவறாமல் இருக்க வேண்டும் என்று
அவருக்குத் தெரியும். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">ஒரு பெருமூச்சிற்குப் பிறகு, “வாருங்கள்
வந்து தேநீர் பருகுங்கள்” என்று சொல்லி சமாளித்தார் பில்போ. </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“ஒரு கோப்பை பீர் கொடுத்தீர்கள் என்றால்
மிகவும் நன்றாக இருக்கும், உங்களுக்கு ஆட்சேபனை எதுவும் இல்லை என்றால். என்ன
சொல்கிறீர்கள் அன்பரே? அத்தோடு, வெள்ளை எள் போட்ட ‘கேக்’குகள்(இனிப்பு ரொட்டி) ஒன்றிரண்டு
உங்களிடம் இருக்கின்றனவா?” என்றான் வெள்ளை தாடி வைத்த பாளின். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“ஒ, நிறைய இருக்கின்றன!” என்று
தன்னை அறியாமலேயே பதில் சொன்ன பில்போ, பீர் பேரல்கள் அடுக்கி வைக்கப்பட்டிருந்த
நிலத்தடி அறை(</span>cellar<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">) நோக்கி
சென்றார். ஒரு பீர் கோப்பை</span>(pint)<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";"> நிரப்ப, நிலத்தடி அறைக்கும், இரவு சாப்பாட்டிற்கு பிறகு உண்ணுவதற்காக அவர்
அன்று மத்தியானம் வேக வைத்த அழகான வட்ட வடிவ எள் கேக்குகளில் இரண்டை எடுக்க சரக்கு
அறைக்கும்(</span>pantry<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">)</span><span lang="TA"> </span><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">சென்றார். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">அவர் திரும்பி வந்த போது,
சாப்பாட்டு மேஜையில், பாளினும் துவாளினும் பழைய நண்பர்களைப்போல
பேசிக்கொண்டிருந்தார்கள் (உண்மை என்னவென்றால், அவர்கள் இருவரும் உடன் பிறந்த
சகோதரர்கள்). பில்போ கேக்கையும், பீரையும் அவர்கள் முன் தடால் என்று வைத்த
அந்நேரத்தில், அழைப்பு மணி அலறியது. உடனே மீண்டும் ஒரு முறை அலறியது. </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“கண்டிப்பாக இது காண்டாளர் தான்”
என்று எண்ணிக்கொண்டு சுரங்கம் போன்ற பாதை வழியாக வேகமாக விரைந்தார் பில்போ. ஆனால்
அது காண்டாளர் இல்லை. இன்னும் இரண்டு கற்குள்ளர்கள் வந்திருந்தார்கள். இருவரும்
மஞ்சள் தாடி, வெள்ளி பெல்ட்டுடன் நீல நிற முக்காடு அணிந்திருந்தார்கள். ஒவ்வொருவரின்
கையிலும் ஒரு மண்வெட்டியும், ஒரு பை நிறைய வேலைப்பாட்டுக் கருவிகளும்
வைத்திருந்தார்கள். கதவு திறக்க ஆரம்பித்த உடனே, எம்பி குதித்தார்கள் உள்ளே. இந்த
தடவை பில்போ கொஞ்சம் கூட ஆச்சரியப்படவில்லை. </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“தாங்களுக்கு எதுவும் உதவி தேவையா,
என் அருமை கற்குள்ளர்களே?” என்றார் பில்போ. </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“நான் <b>கிளி</b>, உங்கள்
சேவைக்காக!” என்றான் ஒரு குள்ளன். “இந்த <b>பிளி</b>’யும் கூட!” என்று அடுக்கினான்
இன்னொரு குள்ளன். இருவரும் தங்கள் நீல நிற முக்காட்டை உருவி எடுத்து விட்டு, தலை
வணங்கி நின்றார்கள்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">இந்த தடவை தன் நல் நடத்தை
நினைவுக்கு வந்ததால் “நான் பில்போ, உங்கள் மற்றும் உங்கள் குடும்பத்தின்
சேவைக்காக!” என்றார் எல்லர்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“துவாளினும் பாளினும் வந்து
விட்டார்கள் போல” என்றான் கிளி. “கூட்டத்தோடு கூட்டமாக சேர்ந்து கொள்ள வேண்டியது
தான்!”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“கூட்டமா!” மனதில் எண்ணிக்கொண்டார்
மிஸ்டர் பாகின்ஸ். “இது போற போக்கு எனக்கு சுத்தமாக பிடிக்கவில்லை. ஒரு நாழி நான்
உட்கார்ந்து கொள்கிறேன். கலங்கும் என் புத்தியை ஒருவழிப் படுத்த வேண்டும். பானம்
ஏதாவது குடித்தால் தான் பதற்றம் குறையும் போலிருக்கிறதே.” அந்த நான்கு கற்குள்ளர்களும்
மேஜயை சுற்றி உட்கார்ந்து கொண்டு, சுரங்கங்கள் பற்றியும், தங்கம் பற்றியும்,
கோபுளின்களுடன் நடந்த கைகலப்பு பற்றியும், டிராகன் சூறையாடியது பற்றியும், இன்னும்
பல பில்போவுக்கு புரியாத விஷயங்கள் பற்றியும், அப்படியே புரிந்தாலும், அவை மிகவும்
அதீத சாகச காரியங்கள் போல் பட்டதால், பில்போவிர்க்கு அவைகளை காது கொடுத்துக்கூட
கேட்கவேண்டும் என்று தோணாத பல செய்திகள் பற்றியும் பேசிக்கொண்டிருந்தார்கள்.
அப்பொழுதான் ஒரு மூலையில் உட்கார்ந்து பில்போ ஒரு வாய் பானம் அருந்தியிருந்தார். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">‘டிங்ங்-டாங்ங்-லிங்ங்’-டேங்ங்
என்று மறுபடியும் அவர் அழைப்பு மணி அலறியது. ஏதோ, ஒரு குரும்புக்கார எல்லச்சிருவன்
அழைப்பு மணியின் கைப்பிடியை பிடுங்க முயற்சிப்பது போல் இருந்தது. “யாரோ
வந்திருக்கிறார்கள் போலிருக்கிறது” என்றார் பில்போ, குழப்பத்துடன். “சத்தத்தை
பார்த்தால், நான்கு பேர் வந்திருக்கிறார்கள் போல தெரிகிறது” என்றான் பிளி. “அத்தோடு,
நாங்கள் வரும்போது, தூரத்தில் அவர்கள் வருவதைப் பார்த்தோம்”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">நம் அப்பாவி எல்லர், வரவேற்பறையிலேயே
தலையில் கைவைத்து உட்கார்ந்து கொண்டார். என்ன நடந்தது, என்ன நடக்கப்போகிறது,
இவர்கள் எல்லோரும் இரவு உணவிற்கு தாங்குவார்களா என்று, யோசிக்க
ஆரம்பித்துவிட்டார். இப்பொழுது, இது வரை இல்லாத அளவுக்கு மீண்டும் அலறியது அழைப்பு
மணி. பில்போ, கதவை நோக்கி கால் தெறிக்க ஓடினார்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">வந்தது நான்கு பேர் இல்லை, ஐந்து
பேர். அவர் வரவேற்பறையில் உட்கார்ந்து யோசித்துக்கொண்டிருந்த சில வினாடிகளில்
இன்னொரு கற்குள்ளன் வந்து சேர்ந்துவிட்டான் போல.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">கதவின் தாழ்ப்பாளை திறந்தாரோ
இல்லையோ, அதற்குள் அவர்கள் எல்லாரும் வீட்டிற்குள்ளே வந்துவிட்டார்கள். எல்லாரும்
தலை குனிந்து ஒருவர் பின் ஒருவராக “உங்கள் சேவைக்காக!” என்று சொன்னார்கள். <b>டோரி,
நோரி, ஓரி, ஆயின்</b> மற்றும் <b>கிளாயின்</b> என்பது தான் அவர்களின் பெயர்கள். விரைவில்,
இரண்டு ஊதா நிற முக்காடுகளும், ஒரு பழுப்பு நிற முக்காடும், ஒரு சாம்பல் நிற
முக்காடும், ஒரு வெள்ளை நிற முக்காடும் கொம்புகளில் தொங்கின. அவர்கள் எல்லாரும்,
தத்தம் தங்கம் அல்லது வெள்ளி பெல்ட்டுகளில் கைவைத்துக்கொண்டு அணிவகுத்து மற்றவர்களுடன்
சேர்ந்துகொள்ள உள்ளே சென்றார்கள். நிஜமாகவே ஒரு கூட்டம் என்று சொல்லும் அளவுக்கு
கற்குள்ளர்களின் எண்ணிக்கை அதிகரித்திருந்தது. சிலர் மது பானம் கேட்டனர், சிலர் உதவிக்கு
ஒரு வாயிற்காவலாளி வேண்டும் என்று கேட்டனர், ஒரு குள்ளன் காபி வேண்டும் என்றான்,
எல்லா குள்ளர்களும் இனிப்பு ரொட்டி(</span>cake<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">) வேண்டும் என்று கேட்டனர். இதனால் நம் எல்லர் கொஞ்ச நேரத்திற்கு
எதைப்பற்றியும் யோசிக்க முடியாமல் இந்த பரிமாறும் வேளையில் ஈடுபட்டிருந்தார். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">ஒரு பெரிய கூஜா நிறைய காபி
அடுப்பில் வைக்கப்பட்டிருந்தது, எள் போட்ட இனிப்பு ரொட்டிகள் காலியாகியிருந்தன,
வெண்ணையும், பால் பவுடரும் கலந்து செய்த உருட்டு பிஸ்கட்டுகளை குள்ளர்கள் தற்போது
சாப்பிட ஆரம்பித்திருந்தனர். அப்பொழுதான் யாரோ வேகமாக கதவைத் தட்டும் சத்தம்
கேட்டது. அழைப்பு மணி ஓசை இல்லை. எல்லரின் அழகான பச்சைக் கதவில் யாரோ ‘டிராட் டிராட்’
என்று தட்டுவது கேட்டது. யாரோ தடி ஒன்றை வைத்து கதவை அடித்துக்கொண்டிருந்தனர்!</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பில்போ சுரங்கப்பாதை வழியாக,
மிகுந்த கோபத்துடன் விரைந்தார். கூட, கடும் குழப்பம் மற்றும் கடுப்புடனும்
ஓடினார். தன் வாழ்க்கையிலேயே, இந்த மாதிரி ஒரு இடர்பாடான புதன்கிழமை வந்ததில்லை. சடாரென்று
கதவைப் பற்றி இழுத்தார் பில்போ. இழுத்த வேகத்தில், அவர்கள் அனைவரும் உள்ளே வந்து
விழுந்தனர், ஒருவர் மேல் ஒருவராக அடுக்கி வைத்தது போல். இன்னும் கொஞ்சம்
கற்குள்ளர்கள். நான்கு குள்ளர்கள். பின்னால், கைத்தடியில் சாய்ந்து நின்று கொண்டு சிரித்துக்கொண்டிருந்தார்
காண்டாளர். அவர் தட்டிய தட்டில், கதவில் ஒரு நல்ல பள்ளமே உருவாகியிருந்தது. அத்தோடு,
அவர் நேற்று காலையில் அவர் போட்டிருந்த ரகசிய அடையாளத்தையும் அழித்திருந்தார். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“பார்த்து! பார்த்து!” என்றார்
காண்டாளர். “நண்பர்களை வாசலில் காக்க வைத்துவிட்டு பிறகு தடாலென்று துப்பாக்கி
வெடிப்பது போல் கதவைத் திறக்கிரீர்களே! வழக்கமான பில்போ போல இல்லையே நீங்கள் இன்று
நடந்து கொள்வது. நானே இவர்களை அறிமுகப்படுத்துகிறேன். இதோ <b>பைபர், போபர்,
பாம்பர்</b> மற்றும் முக்கியமாக <b>தோரின்</b> அவர்கள்!”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பைபர், போபர் மற்றும் பாம்பர்
மூவரும் வரிசையில் நின்று “தங்கள் சேவைக்காக!” என்று கூறினர். பிறகு அவர்கள்,
இரண்டு மஞ்சள் நிற முக்காடுகளையும், ஒரு வெளிர் பச்சை நிற முக்காட்டையும்
மாட்டினார்கள், அத்தோடு, வெள்ளி குஞ்சம் வைத்த கடல் நீல நிற முக்காடும் தொங்கியது
இப்போது. இந்த கடைசி முக்காடு, மாபெரும் முக்கியமான கற்குள்ளன் தோரின்’னுடையது. இது
யாருமல்ல, அந்த மாபெரும் <b>தோரின் ஒகன்சீல்டு </b>தான். அத்தோடு, பில்போவின் மிதியடியில்
குப்புற விழுந்தது, அதுவும், பைபர், போபர் மற்றும் பாம்பர் இவர்கள் தன் மீது அடுக்கடுக்காய்
விழுந்தது கொஞ்சம் கூட பிடிக்கவில்லை இவருக்கு. சொல்லப்போனால், பாம்பர் பார்ப்பதற்கு
மாமிச மலை மாதிரி இருந்தான். தோரின், கர்வத்தோடு சேவை கீவை பற்றி எதுவும்
சொல்லாமல் இருந்தார். பாவம் மிஸ்டர் பாகின்ஸ், பலதடவை மன்னிப்பு கேட்டார்; அதன்
பிறகு தான் தோரின் “பரவாயில்லை விடுங்கள்” என்று முனறிவிட்டு தனது
சிடுசிடுப்புத்தனம் குறைந்தது போல் தோன்றினார்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">வரிசையாகத் தொங்கும் பதிமூன்று
முக்காடுகளையும் (விசேஷங்களில் அணியக்கூடியவை), தனது செம்பருத்தி வடிவ</span>(pointed hat)<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";"> தொப்பியையும் பார்த்து விட்டு, “நாம்
எல்லாரும் வந்துவிட்டோம்” என்றார் காண்டாளர். “நல்ல மகிழ்ச்சியான கொண்டாட்டமாக
இருக்கும் இந்த சந்திப்பு!</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">கடைசியாக வந்த நமக்கு ஏதாவது
உணவும் பானமும் மிச்சம் இருக்கும் என்று நினைக்கிறேன்! என்ன? தேநீரா! இல்லை
வேண்டாம். கொஞ்சம் சிவப்பு மதுரசம்(</span>red wine<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">) இருந்தால் போதும் எனக்கு.” “எனக்கும் கூட கொஞ்சம்!” என்றார் தோரின். “ரச
பெர்ரி பழக் களிம்பும்(</span>raspberry jam<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">), கொஞ்சம் ஆப்பிள் பழ பிட்டும்</span>(apple-tart)<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";"> இருந்தால் போதும் எனக்கு” என்றார் பைபர். “கறி போட்ட வெண்ணைபிட்டு துண்டுகளும்(</span>mince-pies<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">), கொஞ்சம் இளஞ்சூடு காட்டிய
பாலாடைக்கட்டியும்</span>(cheese)<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";"> எனக்கு”
என்றார் போபர். “பன்றிக்கறி களிம்பு பிட்டும்</span>(pork-pie)<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">, துண்டு போட்ட காய்கனிகளும்</span>(salad)<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";"> எனக்கு” என்றார் பாம்பர். “இன்னும் கொஞ்சம் இனிப்பு ரொட்டிகளும்</span>(cake)<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">, நொதித்த பார்லி மதுக்கஷாயமும்</span>(ale)<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">, காபியும் கொண்டு வாருங்கள்” என்று
குரல் கொடுத்தனர் மற்ற குள்ளர்கள் கதவின் உள்ளே இருந்து. </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">சரக்கு அறைகளை நோக்கி ஓடிய எல்லரை
நோக்கி, “ஒன்றிரண்டு முட்டைகளை உடைத்து வறுங்கள், தங்களுடைய நண்பனான எனக்கு!” என்று
கத்தினார் காண்டாளர். “அப்படியே கொஞ்சம் ஊறுகாயும், ஒரு தட்டு ஊற வைத்த
கோழிக்கறியும் எடுத்துக்கொண்டு வந்துவிடுங்கள்!”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span lang="TA" style="font-family: "Latha","sans-serif"; font-size: xx-small; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“என்னுடைய சமையலறை அலமாரிக்குள்ளே
என்ன இருக்குமென்று எனக்குத் தெரிந்த அளவிற்கு தெரியும்போலிருக்கிறது இவர்களுக்கு!”
என்று நினைத்துக்கொண்டார் மிஸ்டர் பாகின்ஸ்.</span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;"><br /></span>
<br />
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">ஏறக்குறைய குழப்பத்திலிருந்த
மிஸ்டர் பாகின்சுக்கு இப்போது லேசாக சந்தேகம் வந்தது; நாசமாய்ப் போன அந்த சாகசப்
பயணம் நேராக நம் வீட்டிற்க்கே வந்து விட்டதோ? எல்லா பாட்டில்களையும்,
தட்டுகளையும், கத்திகளையும், முள் கரண்டிகளையும், கண்ணாடி டம்ளர்களையும்,
பாத்திரங்களையும், ஸ்பூன்களையும் கொண்டு வந்து பரிமாறும் தட்டுகளில் அடுக்கி
வைப்பதற்குள், அவருக்கு கோபம் தலைக்கேறி, முகம் சிவந்து, எரிச்சல் தாண்டவமாடியது.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“நாசமாய்ப் போன இந்த
கற்குள்ளர்கள்!” என்று சத்தம் போட ஆரம்பித்தார். “எதையாவது வந்து எடுத்து
வைக்கிறார்களா இவர்கள்? எல்லா வேலையும், நானே செய்ய வேண்டி இருக்கிறது!” அங்கே
பாருங்கள்! பாளினும், துவாளினும் சமையலறை கதவில் வந்து நின்றார்கள், பிளியும்
கிளியும் அவர்களுக்குப் பின்னே நின்றார்கள், அவர் கரண்டி என்று சொல்வதர்க்குள், பரிமாரும்
பாத்திரங்களை சரக்கென்று எடுத்துச் சென்றார்கள், மட மடவென இரண்டு மேஜைகளை
வரவேற்ப்பரையில் வைத்து, அத்தனை உணவு வகைகளையும் அழகாய் பரப்பி வைத்தார்கள். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">காண்டாளர் கூட்டத்தின் தலைமை
சீட்டில் உட்கார, பதிமூன்று குள்ளர்களும் அவரைச்சுற்றி அமர, பில்போ நெருப்புத்
தொட்டி(</span>fireplace<span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">) அருகில் ஒரு ஸ்டூலில்
உட்கார்ந்து ஒரு பிஸ்கட்டை கொரித்துக்கொண்டே (அவருக்கு இருந்த பசி எங்கோ
ஓடிவிட்டது இப்போது), இதெல்லாம் வழக்கமாக நடக்கக் கூடியவை தான், சாகசமும் இல்லை,
ஒன்றும் இல்லை என்று நல்லதாக எடுத்துக்கொள்ள முயற்ச்சித்தார். குள்ளர்கள்
சாப்பிட்டனர் சாப்பிட்டனர், சாப்பிட்டுக்கொண்டே இருந்தனர்; பேசினர் பேசினர்,
பேசிக்கொண்டே இருந்தனர்; நேரம் ஓடிக்கொண்டே இருந்தது. ஒரு வழியாக எல்லோரும்
சாப்பிட்டு முடித்து, நாற்காலிகளில் சாய்ந்து உட்கார்ந்தார்கள். பில்போ எழுந்து,
தட்டுகளையும், டம்ளர்களையும் எடுக்க ஆரம்பித்தார். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“ராத்திரி இருந்து சாப்பிட்டு
விட்டு தானே போவீர்கள்?” என்றார் மரியாதைக்காக ஆனால் வேண்டா வெறுப்பாய்
கேட்கவில்லை. “கண்டிப்பாக!” என்றார் தோரின். “அதன் பிறகு வெகு நேரத்திற்கு
அப்புறம் தான் வந்த விஷயத்தைப் பற்றியே பேசவேண்டும். இப்போ கண்டிப்பாக ஒரு பாட்டு
வேண்டும். எல்லாவற்றையும் எடுத்து ஓரமாக வையுங்கள்!”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">அதன் பிறகு, பன்னிரண்டு
கற்குள்ளர்களும் (தோரின் மட்டும் வரவில்லை, அவர் மிக முக்கியமானவர், அவர் வராமல்
அங்கேயே காண்டாளரிடம் ஏதோ பேசிக்கொண்டிருந்தார்) எழுந்து கொண்டனர், எல்லா பொருட்களையும்
உயரமாக அடுக்கினார்கள், அகல தட்டில் அடுக்கி எடுத்துச் செல்லாமல், அவர்கள்
கையிலேயே மாபெரும் கோபுரம் போல தட்டுகளை அடுக்கி அதன் உச்சியிலே ஒரு பாட்டிலையும்
வைத்து ஒற்றைக் கையில் கொண்டு சென்றார்கள். நமது எல்லர், அவர்கள் பின்னாலேயே அலறி
அடித்து ஓடினார். “பார்த்து! பார்த்து!” “உங்களுக்கு ஏன் சிரமம்! நானே கொண்டு
போகிறேன்.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">இதையெல்லாம் கேட்காமல் குள்ளர்கள்
பாட ஆரம்பித்தார்கள்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">“தட்டை உடை!
கண்ணாடி டம்ளரை நொறுக்கு!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">கத்தியை மடக்கு!
முள் கரண்டியை முடக்கு!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பில்போவுக்கு
கடுப்பு! அதுதான் கொடுக்கும்!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பாட்டிலை
அடித்து! அதன் மூடியை கொளுத்து!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">துணியைக் கிழித்துப்
பின் எண்ணையை ஊற்று!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பாலையும் ஊற்று,
தரையிலே பார்த்து!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">எலும்புகளை
எடுத்து, படுக்கையிலே கொட்டு!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">சாராயம்
பிடித்து, கதவோரம் ஊத்து!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">சட்டியைப்
பிடித்து, கரண்டியாலே சாத்து!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">இதற்கும் பிறகு,
உடையாமல் இருந்தால்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">உதைத்து,
வராண்டாவில், உருள, விடு!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பில்போவுக்கு
கடுப்பு! அதுதான் கொடுக்கும்!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">அதனால,
பார்த்து! தட்டுகளைப் பார்த்து!</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">பார்த்து! பார்த்து!
பத்திரமாய்ப் பார்த்து!”</span></b><span lang="TA" style="font-family: "Latha","sans-serif"; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";"> </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span lang="TA" style="font-family: "Latha","sans-serif"; font-size: xx-small; mso-ascii-font-family: "Times New Roman"; mso-bidi-language: TA; mso-font-kerning: 16.0pt; mso-hansi-font-family: "Times New Roman";">இல்லை இல்லை. இந்த வன்முறைச்
செயல்களையெல்லாம் அவர்கள் செய்யவில்லை. எல்லர் சமையலறை நடுவில் நின்று கொண்டு
இவர்கள் என்ன செய்கிறார்கள் என்று அங்கும் இங்கும் பார்ப்பதற்குள், மின்னல்
வேகத்தில், அத்தனை பாத்திரங்களையும், கழுவி, துடைத்து, பத்திரமாக அடுக்கி
வைத்துவிட்டார்கள் இந்த கற்குள்ளர்கள்.</span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
</div>
</div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span>
<br />
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">எல்லாரும் திரும்பி வந்து பார்த்த
போது, <b>தோரின்</b>, நெருப்புத் தொட்டி(</span>fireplace
fender<span lang="TA" style="font-family: "Latha","sans-serif";">) மேல் காலை வைத்துக் கொண்டு, வெது
வெதுப்பாக குளிர் காய்ந்து கொண்டே புகை பிடித்துக்கொண்டிருந்தார். மிகப்பெரிய புகை
வளையங்களை விட்டுக்கொண்டிருந்தார். அவர் எங்கு சொல்கிறாரோ, அங்கெல்லாம் புகை
வளையங்கள் சென்றன. கூரையின் புகைபோக்கி அருகே ஒன்று சென்றது. வரவேற்பறையின்,
அலங்கார ஆளுயர கடிகாரத்திற்கு பின்னால் ஒன்று சென்றது, மேஜைக்கு அடியில் ஒன்று
போனது, அறையின் உட்கூரையில் ஒன்று திரிந்து கொண்டிருந்தது. ஆனால், அந்த வளையங்கள்
எங்கே சென்றாலும், காண்டாளரிடம் தப்பிக்க முடியவில்லை. காண்டாளர் தன் சிறிய மண்
குழாயிலிருந்து(</span>smoking pipe<span lang="TA" style="font-family: "Latha","sans-serif";">), சிறு புகை வளையங்களை உருவாக்கி, தோரினுடைய
ஒவ்வொரு, பெரிய புகை வளையங்களின் நடுவே புகுந்து செல்லுமாறு அனுப்பி
வைத்துக்கொண்டிருந்தார். என்ன ஒரு விளையாட்டு! அத்தோடு, நம் மந்திரவாதி காண்டாளரின்
புகை வளையங்கள் பச்சை நிறமாக மாறி திரும்பி வந்து, அவர் தலைக்கு மேலே நின்று
கொண்டன. அதற்குள்ளாகவே ஏகப்பட்ட வளையங்கள் அவர் தலைக்கு மேலே சேர்ந்து, மேக மூட்டம்
போல் ஆகியிருந்தன. அதனால், அறையின் மெல்லிய வெளிச்சத்தில், அவர் வித்தியாசமாக ஏதோ
மந்திர ஜாலங்கள் செய்பவரைப் போல் தோன்றினார். இதை நின்று வேடிக்கை பார்த்துக்கொண்டிருந்த
பில்போவுக்கு, (புகை வளையங்கள் என்றால் அவருக்கு ரொம்ப இஷ்டம்) நேற்று அவர் மலைக்
குன்றை நோக்கி காற்றிலே அனுப்பிய புகை வளையங்களைப் பற்றி பெருமையாக நினைத்தது
நினைவுக்கு வந்ததும், வெட்கமாக இருந்தது. </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“இப்போது ஒரு நல்ல பாட்டு!”
என்றார் தோரின். “உங்கள் வாத்தியங்களை கொண்டாருங்கள்!”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">கிளியும், பிளியும் தங்கள் பைகளில்
இருந்து சிறிய, பிடில் வாத்தியக் கருவிகளைக்(வயலின் போன்ற ஆனால் சிறிய கருவிகள்)
கொண்டு வந்தார்கள். டோரி, நோரி, ஓரி தங்கள் மேலங்கியில்(</span>coat<span lang="TA" style="font-family: "Latha","sans-serif";">) இருந்து புல்லாங்குழல்களை எடுத்தார்கள். பாம்பர், வரவேற்பறையில் இருந்து,
மேளம் ஒன்று கொண்டு வந்தார். பைபரும், போபரும் வெளியே சென்று, ஊன்று கோள்களுடன்
சாத்தி வைக்கப்பட்டிருந்த நாகசுரங்களை(</span>clarinet<span lang="TA" style="font-family: "Latha","sans-serif";">) கொண்டு வந்தார்கள். “ஒரு நிமிடம்! என்னுடையது
திண்ணையில் இருக்கிறது” என்று சொல்லிவிட்டு துவாளினும், பாளினும் கிளம்பினார்கள், “என்னுடையதையும்,
எடுத்துக்கொண்டு வாங்க!” என்றார் தோரின். அவர்கள் திரும்பி வந்த போது, இரண்டு
ஆளுயர (அவர்கள் உயரத்திற்கு) தம்புராக்களையும்(</span>viol<span lang="TA" style="font-family: "Latha","sans-serif";">), அத்தோடு, பச்சை நிற துணி
சுற்றியிருந்த தோரினுடைய யாழ்</span>(harp)<span lang="TA" style="font-family: "Latha","sans-serif";"> கருவியையும் கொண்டு வந்தார்கள். அந்த யாழ்
தங்கத்தில் செய்யப்பட்ட ஒரு அழகான கருவி. தோரின் அதன் நரம்புக் கம்பிகளை மீட்டிய
உடன், சடாலென்று இனிமையான இசை எல்லாரிடமும் இருந்து ஒரே நேரத்தில் ஆரம்பித்தன. இந்த
இனிமையான கீதம் பில்போவை மயக்கி, அப்படியே குன்றின் அடியில் இருந்த தன் எல்லன்
குழியை விட்டு, நீராற்றைத் தாண்டி, எங்கோ கண் காணாத தூர தேசத்தில், இருண்டு போன
ஒரு பிரதேசத்தில், பிரகாசமாக ஜொளிக்கும் நிலவின் கீழே கொண்டு சென்றது. </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">அறையில், குன்றின் பக்கவாட்டில்
இருந்த திறந்த ஜன்னல் வழியாக, அந்த இருள் உள்ளே வந்தது போல் இருந்தது. அவர்கள்
குளிர் காய்ந்து கொண்டிருந்த நெருப்புத் தொட்டியில் தீ காற்றில் மினுக்கியது -இது
ஏப்ரல் மாதம்- இருந்தும் அவர்கள் இசை தொடர்ந்தது. காண்டாளரின் தாடியின் நிழல்
சுவற்றிலே மேலும் கீழும் ஆடிக்கொண்டிருந்தது. நெருப்பு அணைந்து, நிழல்கள் எல்லாம்
மறைந்து, அறை முழுவதும் இருண்டு போனது, ஆனாலும் அவர்கள் நிற்காமல்
வாசித்துக்கொண்டே இருந்தார்கள். திடீரென்று ஒருவர் பாட, அவர்கள் வாசிக்க வாசிக்க இன்னொருவரும்
பாட ஆரம்பித்தனர்; கணீரென்ற அந்த கற்குள்ளர்களின் குரல், பூமிக்கு அடியில் பல
மைல்கள் ஆழத்தில் அமைந்திருந்த அவர்களின் புராதன வீடுகளில் இருந்து ஒலித்தது. இதோ
இது தான் அவர்கள் பாடிய பாட்டு வரிகளின் ஒரு பகுதி.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">“வெகு தூரத்தில், வெண்பனி படர்ந்த மூடுபனிமலையில்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">அதன் குளிரில், மலையின் அடியில், அதி ஆழத்தில்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">பாதாள அறைகளும், புராதன குகைகளும் இருக்கு,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">பொழுது சாய்வதற்குள், போக வேண்டும் நாங்கள்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">மின்னும் மந்திர தங்கத்தை தேடி, போக வேண்டும் நாங்கள்.</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">புராதன கதையில் வரும் கற்குள்ளர்கள், செய்தார்கள்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">மந்திரம். ஓசையெழுப்பும் மணி போல, </span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">அடித்தன சம்மட்டிகள். அமானுஷ்ய ஜந்துக்கள் உறங்கும் </span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">பாதாள சுரங்கங்களில், குன்றுகளின் அடியில், </span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">குடைந்தெடுத்த வராண்டாக்கள். அந்தக்கால ராஜாவுக்கும்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">வேண்தேவர் கோமானுக்கும்(</span></b><b>elvish
lord</b><b><span lang="TA" style="font-family: "Latha","sans-serif";">)</span></b><b>, </b><b><span lang="TA" style="font-family: "Latha","sans-serif";">மின்னும் தங்க</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">குவியல்கள் பல செய்தார்கள். உருக்கினார்கள்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">வார்த்தார்கள், சம்மட்டியால் அடித்து செய்தார்கள்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">ஒளியைப் பிடித்து, வைர வைடூரியங்களில் பதுக்கி,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">உடை வாளின் கைப்பிடியில் பதித்து வைத்தார்கள்.</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">வெள்ளிச் சரமெடுத்து, மாலையாக செய்து,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">நட்சத்திரங்கள் தொங்க விட்டார்கள். ராஜாக்களின்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">தலைக்கவசத்தில், டிராகன் கக்கிய தீயை மாட்டினார்கள்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">வளைத்த கம்பிகளில், நிலவொளியையும், சூரிய</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">ஒளியையும் நெய்தார்கள். </span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">வெகு தூரத்தில், வெண்பனி படர்ந்த மூடுபனிமலையில்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">அதன் குளிரில், மலையின் அடியில், அதி ஆழத்தில்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">பாதாள அறைகளும், புராதன குகைகளும் இருக்கு,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">பொழுது சாய்வதற்குள், போக வேண்டும் நாங்கள்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">எப்போ தொலைந்த எங்கள் தங்கத்தை மீட்க.</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">தனக்கென்று கூஜாக்களை தாங்களே செதுக்கி, தங்கத்திலே</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">யாழிசைக் கருவி செய்து, மனிதனின் வாசம் படாத</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">அந்த பாதாளத்திலே வாழ்ந்திருந்தார்கள். மனிதர்களும்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">வெண் தேவர்களும்(</span></b><b>elf</b><b><span lang="TA" style="font-family: "Latha","sans-serif";">) கேட்டிராத பல பாடல்கள்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">பாடினார்கள். </span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">உச்சியிலே ஆரவாரம் செய்தன பைன் இன மரங்கள்.</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">இரவிலே காற்று புலம்பியது பார்த்து. செந்தணல்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">தீயின் ஜுவாலை பரவியது எங்கும். கைப்பந்தம் </span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">எரிவது போல், எரிந்தன மரங்கள். பள்ளத்தாக்கில்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">மணியோசை எழும்பியது. அண்ணாந்து பார்த்த</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">வீரர்களின் வெளிறிய முகங்கள் பயத்தில். டிராகனின்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">கோபம் தீயை விட மூர்கமாக பாய்ந்தது. அவர்களின்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">கூட கோபுரங்களை சாய்த்தது. வீடுகளை மாய்த்தது.</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">இரவு நிலவின் கீழே எரிந்தது மலை. தங்கள்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">அழிவின் காலடி ஓசை கேட்டது கற்குள்ளர்களுக்கு.</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">தங்கள் வராண்டாக்களை விட்டு ஓடினர். டிராகனின்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">காலால் மிதிபட்டு மாண்டனர், அந்த நிலவொளியின்</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">ஜாமத்தில்.</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">வெகு தூரத்தில், வெண்பனி படர்ந்த மூடுபனிமலையில்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">அதன் குளிரில், மலையின் அடியில், அதி ஆழத்தில்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">பாதாள அறைகளும், புராதன குகைகளும் இருக்கு,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">பொழுது சாய்வதற்குள், போக வேண்டும் நாங்கள்,</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">யாழ்களையும், தங்கத்தையும், டிராகனிடம் இருந்து</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal" style="text-indent: .5in;">
<span style="font-size: x-small;"><b><span lang="TA" style="font-family: "Latha","sans-serif";">மீட்க!“</span></b><b><o:p></o:p></b></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">அவர்கள் பாடப் பாட, கையினாலும்,
தந்திரத்தாலும், மந்திரத்தாலும், செய்யப்படும் அந்த பொக்கிஷங்களின் மேல் ஒரு
பிரியம் வந்து, எல்லரின் நெஞ்சுக்குள்ளே ஊடுருவியது. கட்டுக்கடங்காத பொறாமை
கிளப்பும் அந்த ஆசை, கற்குள்ளர்களின் மனங்களிலே உருகும் அந்த ஆசை, பில்போவை
பிடித்துக்கொண்டது. ஏதோ ஒரு ‘டூக்’ பரம்பரை குணம் அவரின் உள்ளே விழித்துக்கொண்டது.
அந்த பிரம்மாண்ட மலைகளையும், காற்றில் சலசலக்கும் பைன் மரங்களையும், நீர்
வீழ்ச்சிகளையும், மலைக்குகைகளையும் போய்ப் பார்க்க வேண்டும் போல் தோன்றியது. கைத்தடிக்கு
பதிலாக, உடைவாள் அணிந்து போக வேண்டும் போல் இருந்தது. ஜன்னலின் வழியே வெளியே
பார்த்தார். மரங்களுக்கு மேலே அந்த இருண்ட வானத்தில், நட்சத்திரங்கள்
மினுமினுத்தன. அது ஏனோ அவருக்கு இருண்ட குகையில் மின்னும் கற்குள்ளர்களின் புதையலை
ஞாபகப்படுத்தியது. திடீரென்று, நீராற்றைத் தாண்டி இருந்த காட்டிலிருந்து
தீச்சுவாலை ஒன்று கிளம்பியது—யாரோ குளிர் காய மரக்கட்டைகளை கொளுத்துகிறார்கள் போல—ஆனால்,
சூறையாடும் டிராகன்கள் வந்து அமைதியான இந்த குன்றில் உட்கார்ந்துகொண்டு
தீமூட்டுவது போல் தோன்றியது அவருக்கு. அவர் உடல் நடுங்கியது. ஆனால், திடீரென்று,
குன்றின் அடியில், பாகின்ஸ் தெருக்கோடியில் வாழும், வெறும் மிஸ்டர் பாகின்ஸ்’ஆக
மறுபடியும் மாறிவிட்டார்!</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">அவர் எழுந்து நின்றார். உடல் லேசாக
உதறியது. (ஒரு மனது)விளக்கை எடுத்துக்கொண்டு, (இன்னொரு மனது)இல்லை எடுக்கிற மாதிரி
பாவனை செய்துவிட்டு, ஓடிப்போய், ஊக்கபானக் கிடங்கில், பீர் பேரள்கள் பின்னால்
ஒளிந்து கொண்டு, எல்லா கற்குள்ளர்களும் வீட்டை விட்டு போன பிறகு தான் வெளியே
வரவேண்டும் என்று தோன்றியது அவருக்கு. திடீரென்று, இசையும், பாட்டும் நின்று
விட்டது என்று அவருக்கு உரைத்தது. எல்லாரும் அவரையே பார்த்துக்கொண்டிருந்தார்கள்.
இருண்ட அந்த அறையில் அவர்கள் அனைவரின் கண்களும் ஜோளித்தன பில்போவைப் பார்த்து.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">எல்லரின் ஓடி ஒளியும் திட்டத்தை
தெரிந்து கொண்டு விட்டதைப் போல, “எங்கே போகிறீர்கள்?” என்றார் தோரின்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“இருட்டா இருக்கே. விளக்கு
ஏத்தலாம்னு” என்றார் பில்போ பாவமாக.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“எங்களுக்கு இருட்டு பிடிக்கும்.”
என்றனர் குள்ளர்கள். “இரகசியம் பேச இருட்டு தான் சௌகர்யம்! விளக்கு தேவையில்லை.
அவசரமும் இல்லை. விடிவதற்க்கு இன்னும் பல மணி நேரம் இருக்கு.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“சரி சரி!” என்று சொல்லிவிட்டு, வேகமாக
உட்கார்ந்த பில்போ, ஸ்டூலில் உட்காருவதற்கு பதிலாக, பக்கத்தில் இருந்த
நெருப்புத்தொட்டியின் மேல் உட்கார்ந்து, தீயை கிளற வைத்திருந்த கம்பியையும், கரியை
வாரி நெருப்பில் கொட்ட வைத்திருந்த மண்வெட்டியையும் தட்டி விட்டு விட்டார். அவை
தடாலென்று கீழே விழுந்தன.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“ஷ்..ஷ்..ஷ்!” என்றார் காண்டாளர். “தோரினை
கொஞ்சம் பேச விடுங்கள்!”. தோரின் பின் வருமாறு பேச ஆரம்பித்தார்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“காண்டாளரே, குள்ளர்களே மற்றும்
மிஸ்டர் பாகின்ஸ்! இப்பொழுது நாம் நமது நண்பனுமான, கூட்டாளியுமான, பில்போவின்
வீட்டில் இருக்கிறோம். இந்த அற்புதமான, கர்வமான எல்லர்—அவர் கால் விரல் முடி
எப்போதும் கொட்டாமல் இருக்க வாழ்த்துவோம்—அவருடைய திராட்சை மது ரசத்திற்கும்,
பார்லி மதுக்கஷாயத்திற்கும், நன்றி! நன்றி!-” கொஞ்ச நேரம் நிறுத்தி, மூச்சு
வாங்கிக்கொண்டார். அத்தோடு, சம்பிரதாயமாக, பில்போ சில வார்த்தைகள் பேசவும் நேரம்
கொடுத்தார். ஆனால் இந்த புகழ்ச்சி எல்லாம் பில்போவின் தலை மேல் ஏறி ஓடிவிட்டன.
அவர் இப்போது, தலையை வேகமாக ஆட்டி ஆட்டி மறுப்பு தெரிவித்துக்கொண்டிருந்தார். தன்னை
கர்வமானவன் என்று சொல்லிவிட்டாரே! அதுவும் இல்லாமல், கூட்டாளி என்று
கூப்பிடுகிறாரே, என்று தடுமாறிய பில்போவின் வாயிலிருந்து பேச்சே வரவில்லை. அதனால்,
தோரின் தனது பேச்சை தொடர்ந்தார்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“நாம் இப்போது, நமது
திட்டங்களையும், வழிகளையும், வசதிகளையும், கொள்கைகளையும், கருவிகளையும் பற்றி பேச
கூடி இருக்கிறோம். நாம், சீக்கிரம், பொழுது விடிவதற்குள், நமது நீண்ட பயணத்தை
ஆரம்பிக்க போகிறோம். இந்த பயணத்தில் இருந்து, நம்மில் சிலர், அல்லது நாம்
அனைவரும்(நம் ஆலோசகர், நண்பர், சூட்சமமான மந்திரவாதி காண்டாளரைத் தவிர) நிரந்தரமாகத்
திரும்பி வராமல் போகலாம். இது நாம் அனைவரும் மனப்பூர்வமாக முடிவு எடுக்கப்போகும்
நேரம். நம் பயணத்தின் நோக்கம் நம் அனைவருக்கும் தெரியும் என்று நினைக்கிறேன். கண்யவான்
மிஸ்டர் பாகின்ஸ் அவர்களின் நன்மைக்காகவும், நம்மிடையே உள்ள ஒன்றிரண்டு இளம்
கற்குள்ளர்கள்(குறிப்பாக, கிளி, பிளி) இவர்களின் நன்மைக்காகவும், இந்த தருணத்தில்
நமது திட்டத்தைப் பற்றி சுருக்கமாக விளக்க வேண்டியிருக்கிறது—”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">இப்படி பேசுவது தான் தோரினின்
பழக்கம். இவர் மிகவும் முக்கியத்துவம் வாய்ந்த கற்குள்ளர். இவரை விட்டால்,
இப்படியே, மூச்சு வாங்கும் வரை, ஏற்கனவே எல்லாருக்கும் தெரிந்த விஷயத்தையே
பேசிக்கொண்டே போவார். ஆனால் அவர் பேச்சுக்கு, அவமரியாதையாக இடர்பாடு வந்தது. இதற்க்கு
மேலும் பில்போவால் தாங்க முடியவில்லை. அவர் உள்ளே இருந்து ஒரு ஓலம் கிளம்பியது. வெகு
விரைவில், அது சுரங்கத்திலிருந்து வெளிவரும் ரயில் என்ஜின் கூவல் போல
வெடித்துக்கொண்டு வெளியே வந்தது. எல்லா குள்ளர்களும் அதிர்ச்சியில் தடால் என்று
எழுந்ததில், மேஜை குப்புற விழுந்தது. காண்டாளர் தன் மந்திர பிரம்பின் நுனியில் நீல
நிற தீபம் உண்டாக்கி அந்த சிறு எல்லரின் அருகே வெளிச்சம் காட்டினார். பில்போ,
தரையில் கம்பளத்தின் மேலே குனிந்து மண்டியிட்டு, சூட்டில் உருகும் மெழுகு போல
நடுங்கிக்கொண்டிருந்தார். பிறகு குப்புற தரையில் விழுந்து “இடி விழுந்து விட்டது!
இடி விழுந்து விட்டது!” என்று பிதற்ற ஆரம்பித்துவிட்டார் நிற்காமல். வெகு
நேரத்திற்கு அவர் வாயில் வேறெதுவும் வரவைக்க முடியவில்லை. அதனால், அவரைத் தூக்கிக்
கொண்டு போய் அப்பாலிருந்த சோபாவில் கிடத்தி விட்டு, அவர் கைக்கருகே கொஞ்சம்
தண்ணீரையும் வைத்துவிட்டு, தங்களுடைய திட்டங்களைத் தீட்ட மீண்டும் வந்தார்கள். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“கொஞ்சம் உணர்ச்சி வசப்பட்டு
விட்டார், நம் சிறு எல்லர்.” என்றார் காண்டாளர். “அவ்வப்பொழுது ஒரு நூதன வலிப்பு
வந்து விடும், ஆனால் மிகவும் திறமைசாலி. திறமையென்றால் திறமை, நெருக்கடியில்
மாட்டிக்கொண்ட நெருப்பு கக்கும் டிராகனை போன்ற திறமை.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">நெருக்கடியில் மாட்டிய டிராகனை
நீங்கள் நேரே பார்த்திருந்தால், மேலே சொன்னது ஒரு உதாரணத்துக்கு சொன்ன பொய் என்று
உங்களுக்குத் தெரிந்திருக்கும். ஒரு எல்லனின் திறமையை வர்ணிக்க, இப்படி சொல்லலாம்.
ஏன், காளை-கர்ஜிப்பி என்று அழைக்கப்பட்ட டூக் தாத்தா மிகப் பிரம்மாண்ட(மற்ற
எல்லர்களுடன் ஒப்பிடும்போது) உடல் வாகு கொண்டிருந்ததால், குதிரை சவாரி செய்ய
முடிந்த அவருக்கு கூட மேலே சொன்னது பொருந்தாது. அவர் <b>கிராம்</b> மலையில் நடந்த
வயல்காட்டுப் போரில் <b>கோபுளின்</b> படையை எதிர்த்து வெகுண்டு போரிட்டார். அவர்
மரக்கட்டையால் அடித்ததால் <b>கோபுளின் ராஜா </b>தலை அறுந்து விசிறி எறியப்பட்டது. அந்த
தலை வானத்தில் பறந்து, நூறு காத தூரம் தாண்டிப் போய், ஒரு முயல் வலைக்குள்ளே
விழுந்தது. இப்படியாக, அந்த போரில் வெற்றி எய்தார்கள்; அத்தோடு, குழிப்பந்தாட்டம்(</span>golf<span lang="TA" style="font-family: "Latha","sans-serif";">)</span><span lang="TA"> </span><span lang="TA" style="font-family: "Latha","sans-serif";">என்ற விளையாட்டும் உருவானது. </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">இதே சமயத்தில், காளை-கர்ஜிப்பியின்
சந்ததியில் வந்த கனிவான ஒருவர், பக்கத்து அறையில், சுய நினைவுக்கு வந்து
கொண்டிருந்தார். சிறிது நேரம் கழித்து, தண்ணீர் குடித்துவிட்டு, சிறிது
நடுக்கத்துடன், வரவேற்பறையின் கதவருகே வந்தார். அப்போது, கிளாயின்
பேசிக்கொண்டிருப்பது அவருக்கு கேட்டது. “அவர் செய்வார் என்று நினைக்கிறீர்களா?
இந்த எல்லரின் வீர தீரங்களைப் பற்றி காண்டாளர் சொல்வதெல்லாம் கேட்பதற்கு
நன்றாகத்தான் இருக்கிறது. ஆனால் முக்கியமான நேரத்தில் உணர்ச்சிவசப்பட்டு, இப்படியொரு
ஓலமிட்டால், அந்த டிராகன் மட்டுமல்ல, அதன் சொந்தக்கார டிராகன்களும் விழித்து
விடும், பிறகு நம்மை எல்லோரையும், கூண்டோடு கைலாசம் அனுப்பிவிடும். அது என்னவோ
உணர்ச்சி வசப்படுவது போல் இல்லை. திகில் பயத்தில் இட்ட ஓலம் போல் இருந்தது. சொல்லப்போனால்,
இந்த வீட்டின் கதவில் குறியிடவில்லை என்றால், கண்டிப்பாகத் தவறான வீட்டிற்கு வந்து
விட்டேன் என்று திரும்பிப் போயிருப்பேன். இந்த சிறு எல்லர், மிதியடியில் இங்கும்
அங்கும் ஓடி அலறியதைப் பார்த்த உடனே எனக்கு சந்தேகம் வந்து விட்டது. இவரை
கடைக்காரன் என்று வேண்டுமானால் சொல்லலாம், ஆனால், கொள்ளைக்காரன் என்று ஒருப்போதும்
சொல்ல முடியாது!”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">மிஸ்டர் பாகின்ஸ், கதவைத் திறந்து
கொண்டு உள்ளே சென்றார். அவரின் டூக் குடும்ப குணம் வென்று விட்டது. வீர தீர
பில்போவாக மாற அவர் எதையும் இழக்கத் தயாராகிவிட்டார். சிறு எல்லன் தரையில் அங்கும்
இங்கும் ஓடினானா? இப்படி அவரைப்பற்றி பேசியது, அவருக்கு பெரும் ஆக்ரோஷத்தை
உண்டுபண்ணியது. இப்பொழுது அவர் செய்ததை நினைத்து, அவரின் பாகின்ஸ் குடும்ப மனம் பல
முறை நொந்துகொண்டது பின்னாளில். “பில்போ, நீ ஒரு முட்டாள்! சும்மா இருக்காமல்,
தானாகப் போய் தலையை விட்டாயே!” என்று.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">இப்போ...</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“மன்னிக்கவும்,” என்றார் பில்போ.
“நீங்கள் பேசிக்கொண்டிருந்ததை நான் கேட்டேன். நீங்கள் என்ன
பேசிக்கொண்டிருந்தீர்கள் என்று எனக்கு முழுவதுமாக புரியவில்லை. ஆனால் நீங்கள்
கொள்ளைக்காரன் என்று பேசியதைப்பற்றி, நான் கொஞ்சம் சொல்ல விரும்புகிறேன். (அவர் தன்னை
ரோஷக்காரன் என்று சொல்லிக்கொண்டது இதற்க்கு தான்). நான் எதற்கும் லாயக்கு இல்லை
என்று நீங்கள் சொல்கிறீர்கள். உங்களுக்கு தெளிவாக சொல்கிறேன் கேளுங்கள். என்
வீட்டுக்கதவில் எந்த வித அடையாளக்குறியும் இல்லை. ஒரு வாரத்திற்கு முன்பு தான்
வர்ணம் பூசினேன் அந்தக்கதவில். நீங்கள் கண்டிப்பாக தவறான வீட்டிற்கு தான்
வந்திருக்கிறீர்கள். உங்க கேலிக்கூத்தான முகங்களை ஏன் வீட்டு வாசற்படியில் பார்த்த
உடனேயே எனக்கு சந்தேகம் வந்து விட்டது. ஆனால், சரியான வீட்டிற்கு வந்ததாக ஒரு
மரியாதைக்காகவாவது நினைத்துக்கொள்ளலாம் இல்லையா? நான் என்ன செய்ய வேண்டும் என்று
சொல்லுங்கள், முயற்சி செய்கிறேன். இங்கிருந்து நடந்தே சென்று, கிழக்கு திசையின்
கிழக்கிற்கே போகவேண்டுமானாலும் சரி, அங்கே போய் டிராகனாக மாறும் மனிதனுடன், கடைசி
பாலைவனத்தில் சண்டையிட வேண்டுமானாலும் சரி, முயற்சிக்கிறேன். என்னுடைய, கொள்ளுக்கு
கொள்ளு தாத்தா, காளை-கர்ஜிப்பி ஒருமுறை - ”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“ஒ போதும் போதும், அதெல்லாம்
பழங்கதை.” என்றான் கிளாயின். “நான் உங்களைப் பற்றி பேசிக்கொண்டிருந்தேன். நான்
கட்டாயம் சொல்கிறேன், இந்த வீட்டுக்கதவில், அடையாளக்குறி இருந்தது--அதுவும்
வழக்கமாக தொழிலில் இருக்கும் கொள்ளைக்காரர்கள் போடும் அடையாளம். இன்னும் இது
பழக்கத்தில் இருக்கிறதோ என்னவோ, ஆனால் இதைக் கைதேர்ந்த திருடர்கள் பயன்படுத்துவது
உண்டு. <திறமையான திருடனுக்கு ஒரு நல்ல வேலை தேவை. சுவாரசியமான வேலை.
வேலைக்கேற்ற கூலி வேண்டும்> இது தான் அந்த அடையாளத்திற்கு அர்த்தம். திருடன்
இல்லை ஆனால், புதையல் தேடலில், சாமர்த்தியசாலி என்று நீங்கள் சொல்லலாம். சில
திருடர்கள் இப்படிக் கூட செய்வார்கள். எங்களைப் பொறுத்த வரையில், திருடனும் ஒன்று
தான், புதையல் தேடுபவனும் ஒன்று தான். இந்த பகுதியில், அப்படிப்பட்ட ஒரு திருடன்
இருப்பதாகவும், அவன் வேலை தேடிக்கொண்டிருப்பதாகவும், இன்று புதன் கிழமை, தேநீர்
அருந்தும் வேளையில், அவனை சந்திக்க ஏற்பாடு செய்திருப்பதாகவும், காண்டாளர் தான்
கூறியிருந்தார்.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“கண்டிப்பா அடையாளக்குறி இருக்கு.”
என்றார் காண்டாளர். “போட்டதே நான் தான். அதுக்கு ஒரு நல்ல காரணமும் இருக்கு. உங்கள்
பயணத்திற்கு, பதினான்காவதாக ஒரு ஆள் தேவை என்று என்னிடம் கேட்டிருந்தீர்கள். ஆகவே,
நான் மிஸ்டர் பாகின்ஸை தேர்ந்தெடுத்தேன். நான் தவறான ஆளைத் தேர்ந்தெடுத்து
விட்டேன் என்றோ, அல்லது தவறான வீட்டைத் தேர்ந்தெடுத்து விட்டேன் என்றோ யாராவது
இங்கு சொல்லத்துணிந்தால், அப்படியே பதிமூன்று பேரோட நிறுத்திக்கொண்டு நடையைக்கட்டுங்கள்,
உங்களுக்கு வேண்டிய எல்லா துருதிஷ்டங்களையும் அடையுங்கள், அதன் பிறகு மறுபடியும்
போய் நிலக்கரி தோண்டுங்கள்.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">அவர் கோபத்தோடு எரிந்து
விழுந்ததைப் பார்த்த கற்குள்ளன் கிளாயின், தன்னுடைய நாற்காலியிலேயே ஒடுங்கி
விட்டான். பில்போ ஏதோ கேட்க வாயெடுத்த போது, திரும்பி அவரைப் பார்த்து முகத்தை
சுளித்து, அடர்ந்த தன் புருவத்தை உயர்த்தி, பில்போ சடக்கென்று தன் வாயை மூடும் வரை
அவரையே முறைத்துப் பார்த்தார். “அவ்வளவு தான்” என்றார் காண்டாளர். “இதற்கு மேல்
இந்த விஷயத்தை பேச வேண்டாம். நான் மிஸ்டர் பாகின்ஸை நியமித்திருக்கிறேன். அவரே
போதும், உங்கள் எல்லாருக்கும் அவரே போதும். நான் அவரை திருடன் என்று சொன்னால் அவர்
திருடன், இல்லையென்றால், நேரம் வரும்போது அவர் திருடனாக மாறிவிடுவார். நீங்கள்
அனைவரும், நினைப்பதை விட, அவரிடம் இன்னும் பல விஷயங்கள் இருக்கின்றன. ஏன் அவருக்கே
தெரியாத பல விஷயங்கள் அவரிடம் இருக்கின்றன. எனக்கு ஒரு நாள் நீங்கள் இதற்காக நன்றி
சொல்வீர்கள், அது வரை உயிரோடு இருந்தால். பில்போ, குழந்தாய், அந்த விளக்கை எடு,
இதை கொஞ்சம் வெளிச்சத்தில் வைத்து பார்ப்போம்!”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">பெரிய விளக்கின் கீழே, மேஜை மீது,
சிவப்பு நிறத்தில், வரைபடக் காகிதம் ஒன்றை பிரித்து வைத்தார். குள்ளர்கள்
அனைவரும், என்ன ஏது என்று கேட்கவே, “இது, <b>திரார் </b>உருவாக்கிய<b>,</b>
தோரின், உங்களுடைய தாத்தா உருவாக்கிய, அந்த மலையின் கட்டுமான வரைபடம்.” என்று
பதிலளித்தார் காண்டாளர்.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">அதை ஒரு முறை பார்த்து விட்டு,
“இதனால் நமக்கு அதிக பயன் ஏதும் இல்லையே” என்றார் தோரின். “அந்த மலையும், அதைச்
சுற்றி உள்ள நிலங்களைப் பற்றியும் எனக்கு நன்றாக ஞாபகம் இருக்கிறது. அத்தோடு, <b>மிருக்கு-காடு</b>
எங்கிருக்கிறது என்றும், டிராகன்கள் பெருகிக்கிடக்கும் <b>வதங்கு-புதர்க்காடு</b>
எங்கே இருக்கிறதென்றும் தெரியும் எனக்கு.“</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“அங்கே சிவப்பு நிறத்தில் மலை மீது
ஒரு டிராகன் குறியிடப்பட்டுள்ளதே” என்றான் பாளின் “நாம் அங்கே போனாலே, இந்த
டிராகன் இருப்பது மிகத் தெளிவாகத் தெரியுமே? இதற்க்கு எதற்கு ஒரு குறிப்பு?”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“ஒரு முக்கியமான விஷயத்தை பார்க்க
மறந்து விட்டாய்” என்றார் மந்திரவாதி. “அங்கே ஒரு ரகசியக்கதவு, மேற்கு புறம் உள்ள
மந்திர வாசகத்தினால் குறியிடப்பட்டுள்ளதே. மற்ற மந்திர குறியீடுகளில் இருந்து கூட ‘கை’
அடையாளம் போடப்பட்டு சுட்டிக்காட்டப்பட்டுள்ளது பாருங்கள். அந்த வாசல் தான், அதல
பாதாள வராண்டாக்களுக்கு செல்லும் ரகசிய பாதையாகும்.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“அது முன்னொரு காலத்தில் இரகசியப்
பாதையாக இருந்திருக்கலாம்.” என்றார் தோரின். “ஆனால், இப்பவும் அது ரகசியமாகத்தான்
இருக்கிறது என்பதற்கு என்ன உறுதி? பல ஆண்டுகளாக அந்த குகைகளில் வாழ்ந்து வரும் வயதான
அந்த <b>சுமாகு</b> இந்நேரம் அதை கண்டுபிடித்திருக்காதா?”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“கண்டுபிடித்திருக்கலாம். ஆனால்,
அந்த வாசலை அது இது வரைக்கும் பயன்படுத்தி இருக்க முடியாது.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“ஏன்?”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“ஏனென்றால் அது மிகவும், குறுகிய
வாசல். ஐந்து அடி உயரம் தான் இருக்கும், ஒரே சமயத்தில் மூன்று பேர் மட்டுமே அதன்
வழியாக நடந்து செல்ல முடியும். அந்த சந்தில் <b>சுமாகு</b>வால் போக முடியாது. ஏன்,
சின்ன வயதாக அந்த டிராகன் இருக்கும்போது கூட, அத்தனை <b>பள்ளத்தாக்கு நகர்</b>
கற்குள்ளர்களையும், வீரர்களையும், விழுங்கி வயிறு பெருத்த அந்த டிராகனால் அதன்
உள்ளே கண்டிப்பாக போக முடியாது.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">டிராகன்களையே பார்த்திராத, எல்லன்
குழிகளை மட்டுமே பார்த்து பழக்கப்பட்டிருந்த பில்போ, “எனக்கு என்னவோ மிகப் பெரிய
பொந்து போல தான் தோனுகிறது.” என்று கீச்சுக்குரலில் பேசினார். மீண்டும், அவருக்கு
ஆர்வம் அதிகமாகி, உணர்ச்சிவசப்பட்டு, தாம் வாயைப் பொத்திக்கொண்டிருந்தோம் என்ற
விஷயத்தையே அவர் மறந்து விட்டார். அவருக்கு, வரைபடங்கள் என்றால் மிகவும்
பிடிக்கும். தமது வரவேற்பறையில் கூட, உள்ளூர் வரைபடம் ஒன்று பெரிதாக தொங்கியது.
அதில், அவருக்குப் பிடித்த பாதைகளை எல்லாம் சிவப்பு வண்ணத்தில் குறியிட்டுக்
காட்டியிருந்தார். “எப்படி அவ்வளவு பெரிய கதவு, வெளியில் உள்ள யாருக்கும்
தெரியாமல் இருக்கும்?” இவர் மிகவும் சிறிய ஒரு எல்லன் என்பதை நீங்கள் மறந்து
விடக்கூடாது.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“ஒரு கதவை மறைக்க பல வழிகள்
இருக்கின்றன.” என்றார் காண்டாளர். “ஆனால் இந்தக் கதவு எப்படி
மறைக்கப்பட்டிருக்கிறது என்பது, போய்ப் பார்த்தால் தான் தெரியும். இந்த
வரைபடத்தில் இருந்து எனக்கு என்ன தெரிகிறது என்றால், இந்தக் கதவு மூடியிருக்கும்
போது, பார்ப்பதற்கு ஒரு மலைப்பாறை போல் தோன்றும், சொல்லப்போனால், இப்படித்தான்
கற்குள்ளர்கள், ரகசியக் கதவுகளைச் செய்வார்கள், இல்லையா?”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“நீங்கள் சொல்வது முற்றிலும் உண்மை
தான்” என்றார் தோரின். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“மேலும்,” தொடர்ந்தார் காண்டாளர்.
“ஒன்று சொல்ல மறந்து விட்டேன். இந்த வரைபடத்தோடு, ஒரு சிறிய நூதன சாவியும்
செய்யப்பட்டது. இதோ இது தான் அது!” என்று சொல்லி, ஒரு சாவியைக் கொடுத்தார்
தோரினிடம். நீண்ட சிறு குழலுடன், பலவித நுண்ணிய கதுப்புகள் செதுக்கிய அந்தச் சாவி,
வெள்ளியால் செய்யப்பட்டிருந்தது. “சாவி பத்திரம்!”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“கண்டிப்பாக,” என்று சொல்லி
தோரின், தன்னுடைய மேலங்கியின் உள்ளே அவர் கழுத்தில் தொங்கிய சங்கிலியில் மாட்டித்
தொங்கவிட்டார். “இது ஒரு நம்பிக்கையை கூட்டக்கூடிய நல்ல செய்தி. இது வரைக்கும்
நாம் என்ன செய்யப் போகிறோம் என்றே தெரியாமல் இருந்தது. கிழக்கை நோக்கி, சத்தம்
போடாமல் <b>பெரிய ஏரி</b> வரை போகலாம் என்றும், அதற்குப் பிறகு தான் பிரச்சினை
என்றும் நினைத்துக்கொண்டிருந்தோம்.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“அதுக்கு முன்னாடி, கிழக்கில்
ஏதாவது இடர்பாடு இருக்கிறதா?” என்று குறுக்கிட்டார் காண்டாளர். </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“அதற்குப் பிறகு, நாம் <b>விரைவாறு</b>
கரையோரமாக மேலே செல்ல வேண்டும்” என்று தொடர்ந்தார் தோரின், காண்டாளரைக் கண்டு
கொள்ளாமல். “பிறகு, பள்ளத்தாக்கு-நகரின் இடிபாடு வழியாக, மலையடிவாரம் வழியாக செல்ல
வேண்டும். ஆனால் கோட்டையின் முன் வாசல் வழியாக போவதற்கு நம் யாருக்கும்
விருப்பமில்லை. பிறகு, அந்த ஆறு, வெளிக்கிளம்பி, மலையின் தெற்குப்பகுதி வெட்டுப்
பாறை வழியாக வெளியே ஓடுகிறது. அது வழியாகத்தான் அந்த டிராகனும் அடிக்கடி வெளியே
வரும். இன்னும் அது தன் பழக்கத்தை மாற்றிக் கொள்ளவில்லை என்று தான் நினைக்கிறேன்.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“அது கண்டிப்பாக நல்லதில்லை.” என்றார்
மந்திரவாதி. “ஒரு மாபெரும் போர் வீரனோ, அல்லது ஒரு அசகாய சூரனோ நம்மிடம்
இருந்தால், இந்த திட்டம் பலிக்கும். நானும் தேடிப்பார்த்தேன். ஆனால் சூரர்கள்
எல்லாம், கண் கானா தேசத்தில் ஒருவரோடு ஒருவர் போர் புரிந்து கொண்டிருக்கிறார்கள். இந்த
நாட்டு பகுதியில் அசகாய சூர வீரர்கள் யாரும் இல்லை. சொல்ல வேண்டும் என்றால்,
இனிமேல் தான் ஒருவனை உருவாக்க வேண்டும். அத்தோடு, இந்த ஊரில் இருக்கும் போர்
வாள்கள் எல்லாம் மழுங்கிப் போய் கிடக்கின்றன, கோடாலிகள் எல்லாம் மரம் வெட்ட போய்
விட்டன, கவசங்களை எல்லாம் குழந்தைகளைப் போட்டு தாலாட்டவும், சாப்பாட்டுக்
குண்டான்களை மூடவும் தான் பயன்படுத்துகிறார்கள். டிராகன்கள் எல்லாம் தூர நாட்டில்
சந்தோஷமாக இருக்கின்றன. அதனால், அவைகள் எல்லாம் பழங்கதைகளாகப் போய்விட்டன. அதனால்
தான் சொல்கிறேன், சண்டை போடுவதை விட, திருடுவது சுலபம். நல்லவேளை, ஒரு
பக்கவாட்டுக் கதவு இருப்பது எனக்கு நினைவு வந்தது. இதோ நம்முடைய, குள்ள பில்போ
பாகின்ஸ் தான் அந்த நிர்ணயிக்கப்பட்ட திருடன். இப்போது நாம் சில திட்டங்களை தீட்டுவோம்.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“அப்படி சொல்கிறீர்களா? சரி
ஆகட்டும்.” என்றார் தோரின். “நம் கைதேர்ந்த திருடன், ஏதாவது, ஆலோசனை சொல்லுவாரா?”
என்று மிகுந்த மரியாதையுடன் கேட்பது போல, பாசாங்கு செய்தார் பில்போவை நோக்கி.</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“முதலில் சில விவரங்களை கூறினால்
நன்றாக இருக்கும்.” என்றார் பில்போ லேசான நடுக்கத்துடன். சற்று குழம்பி
இருந்தாலும், போகிற போக்கில் போகத் துணிந்துவிட்டார். “இந்த தங்கம், டிராகன்
பற்றியும், எப்படி இவை அங்கே போனது, யாருக்கு சொந்தம், இன்னும் கொஞ்சம் விவரம்
சொல்ல முடியுமா?”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“கிழிந்தது!” என்றார் தோரின். “உங்களிடம்
ஒரு வரைபடம் இருக்கிறது அல்லவா? அத்தோடு, இதுவரை நாங்கள் பாடிய பாட்டை
கேட்கவில்லையா? மணிக்கணக்காய் இதைப்பற்றி தானே பேசிக்கொண்டிருந்தோம்?”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“என்ன இருந்தாலும், கொஞ்சம் நேராக
சொன்னால் நன்றாக இருக்கும்.” என்றார் ஒட்டாரமாய், தன்னிடம் கடன் வாங்க
வருபவர்களிடம் பேசுவதை போல கறாராய். அத்தோடு, அறிவுக்கூர்மையுடனும், விவேகமாகவும்,
தொழில் நுட்பம் தெரிந்தது போலவும், காண்டாளரின் சிபாரிசுக்கு ஈடுகொடுக்கும்
அளவுக்குத் தோன்ற வேண்டும் என்றும் முயற்சி செய்தார். “அதே போல, இதில் என்ன அபாயம்
இருக்கிறது, எனக்கு எவ்வளவு செலவு ஆகும், எவ்வளவு நாளாகும், என்ன சம்பளம்,
இப்படிப்பட்ட விஷயங்களைச் சொல்லுங்கள்.” அதாவது, அவர் உண்மையிலேயே என்ன கேட்டார்
என்றால் “இதனால் எனக்கென்ன லாபம்? நான் உயிரோடு திரும்பி வருவேனா?”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><span lang="TA" style="font-family: "Latha","sans-serif";">“சரி சரி” என்றார் தோரின். “பலப்பல
வருடங்களுக்கு முன்னாள், என் தாத்தா <b>திரார்</b> அவர்களின் காலத்தில், தூர
வடக்குப் பகுதியில் இருந்து என்னுடைய குடும்பமே துரத்தியடிக்கப்பட்டது. பிறகு,
தங்கள் புதையல்கள் மற்றும் வேலைப்பாட்டுக் கருவிகளுடன், இதோ இந்த வரைபடத்தில்
இருக்கும் இந்த மலைக்கு வந்து சேர்ந்தார்கள். இந்த மலை, எங்கள் முன்னோர்களில்
ஒருவரான, <b>திராயின்</b> என்பவரால் முன்பாகவே கண்டுபிடிக்கப்பட்டிருந்தது. ஆனால்,
இப்பொழுது தான் இந்த மலையைக் குடைந்து, சுரங்கப்பாதைகள் பல அமைத்து, பெரிய பெரிய
மண்டபங்கள் அமைத்து, பிரம்மாண்ட தொழிற்சாலைகளை அமைத்தார்கள்- அத்தோடு, ஏகப்பட்ட
தங்கங்களையும், விலையுயர்ந்த கற்களையும், வைர வைடூர்யங்களையும், கண்டெடுத்தார்கள்.
இதனால், அவர்கள் செல்வங்கள் கூடின, புகழ் பரவியது, என்னுடைய, தாத்தா, மறுபடியும்
ராஜாவகினார் அந்த மலையின் பாதாளத்திற்கு. மலையின் தெற்கு பகுதியில் வாழ்ந்த மனிதர்களும்
அவரைப் போற்றி மதித்தனர். கூடிய விரைவில், அது விரைவாறு வரை பரவியது. மலையடிவாரத்தில்
பறந்து விரிந்த கிடந்த பள்ளத்தாக்கு முழுவதும் பரவியது. பள்ளத்தாக்கில்,
களிக்கொண்டாட்டங்களுக்காக பள்ளத்தாக்கு-நகரையும் கட்டினார்கள். பல நாட்டு
அரசர்கள், எங்கள் கொல்லர்கள் உதவி கேட்டு செய்தி அனுப்பினார்கள். மிகவும் குறைந்த
திறமை கொண்ட கொல்லர்களுக்கு கூட கோடி கோடியாய் பரிசு கொடுத்தார்கள். பல
தகப்பன்மார்கள் தங்கள் பிள்ளைகளை எடுபிடி வேலைக்கு சேர்த்துக்கொண்டு தொழில்
கற்றுக்கொடுக்குமாறு எங்களிடம் வேண்டுவார்கள். அதற்காக நிறைய உணவுப்பொருட்கள் வேறு
கொட்டிக்கொடுப்பார்கள் எங்களுக்கு. அதனால், நாங்கள் உணவுக்கு விவசாயம் கூட செய்ய
வேண்டிய அவசியம் இல்லாமல் போனது. அது ஒரு அருமையான காலம். எங்களில் மிகுந்த ஏழைகள்
கூட, செலவு செய்யவும், வட்டிக்கு விடவும், பணம் வைத்திருந்தார்கள். அழகான
பொருட்களை ஆசைப்பட்டு செய்ய நிறைய ஓய்வு நேரமும் இருந்தது, மிகவும் அற்புதமான,
விந்தையான மந்திர பொம்மைகள் பல செய்தோம். அந்த மாதிரி பொருட்களை இப்போது கண்ணால்
கூட எங்கும் காண முடியாது. என்னுடைய தாத்தாவின் மண்டபங்களில், கவசங்களும்,
நகைகளும், கைவினைப்பொருட்களும், கோப்பைகளும் நிரம்பி வழிந்தன. பள்ளத்தாக்கு நகரின்
பொம்மை சந்தை, வடக்குப் பிரதேசம் எங்கும் வியந்து போற்றப்பட்டது.”</span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-size: x-small;"><br /></span></div>
<span lang="TA" style="font-family: "Latha","sans-serif"; font-size: x-small;">“இந்த புகழ் தான், அந்த
டிராகனையும் அங்கே கொண்டு வந்தது. டிராகன்கள் வழக்கமாக, தங்கத்தையும், நகைகளையும்,
மனிதர்களிடமிருந்தும், கற்குள்ளர்களிடமிருந்தும், வேண்தேவர்களிடமிருந்தும்
திருடும் குணாதிசயம் கொண்டவை. எங்கு புதையல் கிடைத்தாலும், அவை அதை கொள்ளையடித்து,
அவை சாகும் வரை(டிராகன்கள் கொல்லப்பட்டாலொழிய, அவை சாகவே சாகாது) பாதுகாக்கும். ஆனால்
ஒரு குண்டு மணியைக் கூட அவை செலவு செய்து மகிழாது. சொல்லப்போனால், கைதேர்ந்த
வேலைப்பாட்டை தரம் பிரிக்கத் தெரியாது அவைகளுக்கு. ஆனால், சந்தையில், எது எவ்வளவு
விலை போகும் என்று ஏறக்குறைய அவைகளுக்குத் தெரியும். ஒரு நகை கூட செய்யத்
தெரியாது. அவைகளின் பாதுகாப்பு கவசத்தில் ஒரு உலோகத் தட்டு தளர்ந்தாலும் அதை சரி
செய்யத் தெரியாது. அப்போது, வடக்கில், ஏகப்பட்ட டிராகன்கள் இருந்தன. அதனால்
அவற்றிற்கு தங்கம் கிடைப்பது அரிதாக இருந்தது போல. கற்குள்ளர்கள், தெற்கு நோக்கி
பிழைப்பு தேடினர். டிராகன்களின் அட்டுழியம் மோசமான நிலையை அடைந்தது. அதிலே,
மிகவும் பேராசை கொண்ட, சக்திவாய்ந்த, வக்கிர புத்தி கொண்ட சுமாகு என்ற அற்ப புழு
ஒன்று இருந்தது. ஒரு நாள், அது வானத்திலே பறந்து, தெற்கு நோக்கி வந்தது. முதலில்
ஏதோ வடக்கிலிருந்து சூறாவளி புயல் வருகிறது என்று நாங்கள் நினைத்தோம். மலையின்
மேலே இருந்த பைன் மரங்கள் பேயாட்டம் ஆடி காற்றில் முறிந்தன. மலையைத் தாண்டி வெளியே
சென்றிருந்த கற்குள்ளர்கள் சிலர் (அதிஷ்ட வசமாக, சாகசபயணம் செல்வதில் பேர் வாங்கிய
இளம் காளையாக திரிந்து கொண்டிருந்த நான், தொடரும்.....)”</span></div>
</div>
Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-76886755296636838212012-12-15T02:07:00.000+05:302012-12-29T02:10:29.500+05:30Google vs SearchKo - Tamil Translation war<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://translate.google.com/?sl=en&tl=ta&js=n&prev=_t&hl=en&ie=UTF-8&eotf=1&text=collect+my+wits#en/ta/flummox">http://translate.google.com/?sl=en&tl=ta&js=n&prev=_t&hl=en&ie=UTF-8&eotf=1&text=collect+my+wits#en/ta/flummox</a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkkuLFSzAwj0pkqagv11YFLC17C7NS7K4Peq3QmuvZTvlGN-B0-cL3v8lTnzXKiUj9kI1dYc-PXZoM7D9qIvk9PMJqqblhyphenhyphen4autg4kSYmrS1-s13NjS0ZMJELQI5GMbyvanULb3ghXdFo4/s1600/2012-12-29_0157.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkkuLFSzAwj0pkqagv11YFLC17C7NS7K4Peq3QmuvZTvlGN-B0-cL3v8lTnzXKiUj9kI1dYc-PXZoM7D9qIvk9PMJqqblhyphenhyphen4autg4kSYmrS1-s13NjS0ZMJELQI5GMbyvanULb3ghXdFo4/s640/2012-12-29_0157.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<a href="http://searchko.in/english-tamildictionary.jsp?etextbox=flummox">http://searchko.in/english-tamildictionary.jsp?etextbox=flummox</a><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-Ocw2NrxFBt0ptpR5t35_veUiTDJYgqR0Z8Lz-mPMCpzgKcQf1PWA3efOe4W6fm1AIX0dKeAe4gNxgd0hH3VkhZEOlcd5FdnO5ihk_keEOrIt5-BUZCTdprE2Xsl9dIHzuWEpUKs3MiYb/s1600/2012-12-29_0158.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="405" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-Ocw2NrxFBt0ptpR5t35_veUiTDJYgqR0Z8Lz-mPMCpzgKcQf1PWA3efOe4W6fm1AIX0dKeAe4gNxgd0hH3VkhZEOlcd5FdnO5ihk_keEOrIt5-BUZCTdprE2Xsl9dIHzuWEpUKs3MiYb/s640/2012-12-29_0158.png" width="640" /></a></div>
<br />
<div>
<br /></div>
<div>
Looks like SearchKo people have done a great job translating most unusual English words (as per Tamil culture, it is unusual) while Google fails to do so. But then, Google is right behind SearchKo for now.</div>
</div>
Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com1tag:blogger.com,1999:blog-5659366926389737478.post-10256801214613076912012-11-03T02:31:00.000+05:302012-11-03T02:37:35.573+05:30This is the end.<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<b style="border: 0px none; font-family: Verdana, Arial; font-size: 13px; margin: 0px; padding: 0px; text-align: center;"> "Skyfall"</b>[<a href="http://www.woo55.pk/adata/5096/Adele%20-%20Skyfall%20(Radio%20Rip)%20(www.SongsLover.pk).mp3" target="_blank">listen</a> here]<br />
<br />
<div style="border: 0px none; font-family: Verdana, Arial; font-size: 13px; margin: 0px 10px; padding: 0px; text-align: center;">
This is the end<br />
Hold your breath and count to ten<br />
Feel the earth move and then<br />
Hear my heart burst again<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
For this is the end<br />
I’ve drowned and dreamt this moment<br />
So overdue I owe them<br />
Swept away, I’m stolen<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
Let the sky fall<br />
When it crumbles<br />
We will stand tall<br />
Face it all together<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
Let the sky fall<br />
When it crumbles<br />
We will stand tall<br />
Face it all together<br />
At skyfall<br />
At skyfall<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
Skyfall is where we start<br />
A thousand miles and poles apart<br />
Where worlds collide and days are dark<br />
You may have my number, you can take my name<br />
But you’ll never have my heart<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
Let the sky fall<br />
When it crumbles<br />
We will stand tall<br />
Face it all together<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
Let the sky fall<br />
When it crumbles<br />
We will stand tall<br />
Face it all together<br />
At skyfall<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
<i style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;">[2x]</i><br />
(Let the sky fall<br />
When it crumbles<br />
We will stand tall)<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
Where you go I go<br />
What you see I see<br />
I know I’d never be me<br />
Without the security<br />
Of your loving arms<br />
Keeping me from harm<br />
Put your hand in my hand<br />
And we’ll stand<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
Let the sky fall<br />
When it crumbles<br />
We will stand tall<br />
Face it all together<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
Let the sky fall<br />
When it crumbles<br />
We will stand tall<br />
Face it all together<br />
At skyfall<br />
<br style="border: 0px none; font-size: 1em; margin: 0px; padding: 0px;" />
Let the sky fall<br />
We will stand tall<br />
At skyfall</div>
<div>
<br /></div>
</div>
Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-37512323426709862962012-08-22T18:35:00.002+05:302012-08-22T18:45:42.528+05:30Tips on GIT<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
GIT<br />
<br />
USEFUL GIT COMMANDS<br />
-------------------------------<br />
<br />
Clone a repo::<span style="color: red;"> git clone repository_url</span><br />
<br />
To display whitespace errors <span style="color: red;"># git diff --check</span><br />
To revert a modified file to original state(unmodified) <span style="color: red;"># git checkout -- file_name </span><file_name> </file_name><br />
To see list of modified and untracked files <span style="color: red;"># git status</span><br />
To stage a file/to mark a file to be committed in the next checkin command <span style="color: red;"># git add file_name</span><file_name></file_name><br />
To display diff of all modified files <span style="color: red;"># git diff</span><br />
To display last n commits<span style="color: red;"> # git log –n</span><br />
To list only the direct commits to a branch, switch to that branch and do<span style="color: red;"> # git rev-list origin..HEAD --not $(git merge-base --all origin HEAD) --first-parent --pretty --no-merges</span><br />
<br />
BRANCH<br />
------<br />
To see the branches you have<span style="color: red;"> # git branch</span><br />
TO list all branches in the origin server <span style="color: red;">#git branch --remotes</span><br />
To switch to another branch <span style="color: red;"># git checkout </span><branch_name></branch_name><br />
To force branch switching even when it refuses<span style="color: red;"> #git checkout branch_name --force</span><br />
To track a remote branch: <span style="color: red;">#git checkout --track origin/branch_name</span><br />
To delete a local branch<span style="color: red;"> #git branch -d branch_name</span><br />
To force delete a local branch<span style="color: red;"> #git branch -D branch_name</span><br />
To delete a remote branch from the remote server<span style="color: red;"> #git push origin :the_remote_branch</span><br />
<br />
To list all files committed in the last commit<span style="color: red;"> # git show --pretty="format:" --name-only</span><br />
To list all files committed in a particular commit object <span style="color: red;"># git show --pretty="format:" --name-only </span><commit_id></commit_id><br />
TO rename a branch<span style="color: red;"> #git branch (-m | -M) old_branch new_branch </span>(old_branch optional)<br />
To send a new local branch to remote server<span style="color: red;"> # git push -u origin new_branch_name</span> [this creates a branch in the server with the same name]<br />
<br />
RESET A BRANCH TO UPSTREAM STATE <span style="color: red;"># git reset --hard origin/master</span> (resets the master to upstream state; run this command repeatedly if it is not working once)<br />
<br />
HISTORY/REVISION<br />
-----------------<br />
To list changes for a file<span style="color: red;"> #git log -- file_name</span><br />
To list changes for a file graphically <span style="color: red;"># gitk file_name</span><br />
<br />
HOW TO RESOLVE CONFLICTS / MERGING<br />
---------------------------------<br />
After seeing a conflict, you can do two things:<br />
<br />
Decide not to merge. The only clean-ups you need are to reset the index file to the HEAD commit to reverse 2. and to clean up working tree changes made by 2. and 3.; <span style="color: red;">git merge --abort</span> can be used for this.<br />
<br />
Resolve the conflicts. Git will mark the conflicts in the working tree. Edit the files into shape and git add them to the index. Use git commit to seal the deal.<br />
<br />
You can work through the conflict with a number of tools:<br />
<br />
Use a mergetool. git mergetool to launch a graphical mergetool which will work you through the merge.<br />
<br />
Look at the diffs. git diff will show a three-way diff, highlighting changes from both the HEAD and MERGE_HEAD versions.<br />
<br />
Look at the diffs from each branch. git log --merge -p <path> will show diffs first for the HEAD version and then the MERGE_HEAD version.</path><br />
<br />
Look at the originals. git show :1:filename shows the common ancestor, git show :2:filename shows the HEAD version, and git show :3:filename shows the MERGE_HEAD version.<br />
<br />
During merge conflict do the following:<br />
<br />
<span style="color: red;">#git mergetool --tool=tortoisemerge </span>{make sure that you have tortoise git installed to use this merge tool}<br />
<span style="color: red;">#git commit -m "Manual merging master into this branch"</span><br />
<span style="color: red;">#git push {send to remote server}</span><br />
<br />
STASH<br />
-----<br />
To stash the current working directory<span style="color: red;"> #git stash</span><br />
To list stashes available <span style="color: red;">#git stash [show|list]</span><br />
To discard a stash<span style="color: red;"> #git stash drop</span><br />
<br />
#no complex server setup is required to use GIT<br />
<span style="color: red;">$git init myproject</span><br />
Creates directory called myproject<br />
<br />
<span style="color: red;">$git add . </span>(notices files and readies them for recording)<br />
<br />
<span style="color: red;">$git commit -m "" </span>(commits the final version)<br />
<br />
#the final push downloads the central copy and merges with the local commits and offers help on any conflict during auto merge. This process happens to everybody who works parallelly. So, conflict resolution is localized.<br />
<br />
Git Config<br />
----------<br />
<br />
$ git config --list<br />
core.symlinks=false<br />
core.autocrlf=true<br />
color.diff=auto<br />
color.status=auto<br />
color.branch=auto<br />
color.interactive=true<br />
pack.packsizelimit=2g<br />
help.format=html<br />
http.sslcainfo=/bin/curl-ca-bundle.crt<br />
sendemail.smtpserver=/bin/msmtp.exe<br />
diff.astextplain.textconv=astextplain<br />
rebase.autosquash=true<br />
user.name=yourname<br />
user.email=youremail<br />
push.default=upstream<br />
<br />
Git Line Endings<br />
----------------<br />
To list a property<span style="color: red;"> #git config --global proptery_name</span><br />
<br />
core.eol = native – The default.<br />
core.autocrlf = true [back and forth conversion of line endings in commit and checkouts]<br />
core.safecrlf = true [backout of autoconversion if unsafe file is detected]<br />
<br />
The following are added in .gitattributes files:::-<br />
<br />
*.txt crlf in .gitattributes file enables auto crlf conversions for text files<br />
*.txt -crlf in .gitattributes file disables auto crlf conversions for text files<br />
*.txt crlf=input in .gitattributes file enables auto conversion only in commits but not in checkout on working directory<br />
*.txt text [marks all .txt files as text files]<br />
*.txt -text [.txt files will not go through auto crlf conversion]<br />
*.txt text=auto [git auto detects .txt files as text files or not for crlf conversion; relies on git's internal binary detection heuristics]<br />
*.png binary [marks .png files as binary files]<br />
* text=auto [tell git to detect all text files and automatically normalize them (convert CRLF to LF)]<br />
<div>
<br /></div>
<div>
EGit(For Eclipse)<br />
------------------<br />
#Share the project to git first (right click, open Team menu and do Share)<br />
#Try to pull the project and if you get proxy error, do the following:-<br />
1.Set HOME env variable pointing to your user home(C:\Users\user on Win7)<br />
2.Set GIT_SSH=C:\Program Files (x86)\Git\bin\ssh.exe as env variable<br />
3.Create .bash_rc file in your user home with 'GIT_SSH="C:\Program Files (x86)\Git\bin\ssh.exe"' line<br />
4.Relogin to your machine<br />
<br />
[THIS DIDN'T WORK. OF COURSE PROXY ERROR WENT AWAY, BUT IT WOULDN'T PULL AND WAITS FOREVER]<br />
<br />
This is due to signed certificate used for ssh in git. If you can reconfig the certificate without password, it would work.<br />
<br /></div>
</div>
Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-58940698580718052122012-06-07T09:14:00.000+05:302012-07-17T23:17:45.344+05:30GIST NOTES 23 - Tidbits<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-size: large;">GIST NOTES 23 - Tidbits</span><br />
<br />
<br />
*EventListener is in java.util package and it is the same listener implemented by all swing components<br />
*EventListener is a marker interface, but why?<br />
*RandomAccess is a marker interface, just to let others know that they can alter their behavior to provide good performance<br />
*Collections.sort() uses Arrays.sort() internally<br />
*Collections class is not class-wide generics class; generics usage is localized to its static methods (makes sense, because it is a util class after all)<br />
*the class Class is genericfied as well<br />
<br />
*Annotations<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>-not part of the program<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>-info for compiler(detect errors and suppress warnings)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>-compile time and deployment time processing(tools that process annotations)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>-runtime processing(sometimes available at runtime)<br />
<br />
*infinite loops in initializer blocks(static and non-static) causes compiler error "unreachable statement" pointing the member variables<br />
<br />
*<span class="Apple-tab-span" style="white-space: pre;"> </span>while(true);<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>while(true){}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>while(false);<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>while(false){}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>for(;;);<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>for(;;){}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#all of the above statements cause compiler error with 'unreachable statement' when placed in initializer blocks<br />
<br />
* Another important feature of JWS(Java Web Start) is its ability to run your application in a sandbox - a restricted container based on Java security architecture. But, unlike an applet, your application can gain access to local system resources like the filesystem, printer and system clipboard using the JNLP API even if it comes from an untrusted environment, after prompting the user for confirmation.<br />
<br />
* in java, while reading html document streams from internet, they end with "\\\\L" token delimiter.<br />
<br />
* Desktop Applications are commonly known as rich clients<br />
* A thin clinet is a web client or a simple front end<br />
* Rich client is any client with much more of logic, user interface and interactivity than any web client<br />
<br />
* Java 5 brings ConcurrentHashMap, in which only a part of the Map is locked, such that many threads can access different parts simultaneously. This optimization is possible, since HashMap stores their data in buckets. This optimization is known as lock striping.<br />
<br />
*Lock and ReentrantLock<br />
<br />
Why create a new locking mechanism that is so similar to intrinsic locking ?Intrinsic locking works fine in most situations but has some functional limitations it is not possible to interrupt a thread waiting to acquire a lock, or to attempt to acquire a lock without being willing to wait for it forever. Intrinsic locks also must be released in the same block of code in which they are acquired; this simplifies coding and interacts nicely with exception handling, but makes non block structured locking disciplines impossible. None of these are reasons to abandon synchronized, but in some cases a more flexible locking mechanism offers better liveness or performance.<br />
<br />
*ReentrantLock requires that the Lock be held when calling signal or signalAll, but Lock implementations are permitted to construct Conditions that do not have this requirement.<br />
<br />
*AQS is a framework for building locks and synchronizers: Abstract-QueuedSynchronizer (AQS)<br />
<br />
*AbstractQueuedSynchronizer uses Template method pattern to let subclasses define new locking mechanisms; try**() methods in AQS are hooks left for subclasses to implement<br />
<br />
*SerialVersionUID of all enums is 0L<br />
<br />
* "java -X" displays non-standard command line options<br />
* The -X options are non-standard and subject to change without notice.<br />
* -XX option is used to set gc related params<br />
<br />
*posix (portable operating system interface) threads do not have reentrancy(lock is issued on per invocation basis) whereas java default locks are issued on per thread basis<br />
<br />
* Forest - group of trees with no connection between them (Data Structures); removing root node of a tree results in a forest (due to the disjoint subtrees)<br />
<br />
*The distinctions between a binary tree and a tree should be analyzed. First of all there is no tree having zero nodes, but there is an empty binary tree.<br />
<br />
*The first is a skewed tree, skewed to the left and there is a corresponding one which skews to the right. All nodes of the binary tree are on the left side (or all on right side) in a slanting straight line.<br />
<br />
*Complete binary tree - all nodes have either 2 children or no children<br />
<br />
*A Complete Binary Tree can be stored in an array and easy to find parent and children of any node with given node index in the array<br />
<br />
..... | PARENT | <-----i/2----> | NODE | <-----i----> | CHILD1 | CHILD2 | .....<br />
<br />
where i/2 and i are the distances and i is the index of NODE in the array; this is because at every level no.of nodes double;<br />
<br />
PARENT -> i/2<br />
LEFTCHILD -> 2i<br />
RIGHTCHILD -> 2i+1<br />
<br />
*XPCOM (Cross Platform Component Object Model)<br />
*WPA/WPA2 - WiFi Protected Access (new system)<br />
*WEA - Wired Equivalent Privacy (old system)<br />
*WiFi - Wireless Fidelity (came from HiFi - High Fidelity in audio equipment classification)<br />
*Temporal Key Integrity Protocol (TKIP), was adopted for WPA<br />
*WPA2 uses AES<br />
*<% %> is used to place java code in jsp file<br />
*<%=value%> is used to print the value of java variable 'value' in html from jsp<br />
*I18N - internationlization(18 signifies no.of letters between I and N)<br />
*L10N - localization(10 letters between L and N)<br />
<div>
<br /></div>
</div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-26163839849076999572012-06-07T08:04:00.000+05:302012-06-11T13:38:36.158+05:30GIST NOTES 22 - SNMP<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div class="MsoNormal">
</div>
<div class="MsoNormal">
<span style="font-size: large;">GIST NOTES 22 - SNMP</span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books/sources on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span></div>
<div class="MsoNormal">
<span style="color: red;"><b><br /></b></span></div>
<div class="MsoNormal">
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span></div>
<br />
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
>SNMP uses MIB<o:p></o:p></div>
<div class="MsoNormal">
>MIBs use notation defined by ASN.1(Abstract Syntax
Notation)<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
BER<o:p></o:p></div>
<div class="MsoNormal">
---<o:p></o:p></div>
<div class="MsoNormal">
>BER(Basic Encoding Rules) of ASN is used<o:p></o:p></div>
<div class="MsoNormal">
>BER uses notation TLV(Type-Length-Value) form<o:p></o:p></div>
<div class="MsoNormal">
>Type - 8bits<o:p></o:p></div>
<div class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: .05in; mso-outline-level: 3;">
<b><span style="font-family: Arial, sans-serif; font-size: 13pt;"><br />
Type<o:p></o:p></span></b></div>
<div class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 6.0pt; margin-left: 0in; margin-right: 0in; margin-top: 4.8pt;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">The type field is an octet specifying the characteristics of the
value field.<o:p></o:p></span></div>
<table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" style="background: white; border-collapse: collapse; border: none; mso-border-alt: solid #AAAAAA .75pt; mso-yfti-tbllook: 1184;">
<tbody>
<tr>
<td colspan="8" style="background: #F2F2F2; border: none; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">Type identifier octet<o:p></o:p></span></b></div>
</td>
</tr>
<tr>
<td style="background: #F2F2F2; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">8<o:p></o:p></span></b></div>
</td>
<td style="background: #F2F2F2; border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">7<o:p></o:p></span></b></div>
</td>
<td style="background: #F2F2F2; border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">6<o:p></o:p></span></b></div>
</td>
<td style="background: #F2F2F2; border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">5<o:p></o:p></span></b></div>
</td>
<td style="background: #F2F2F2; border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">4<o:p></o:p></span></b></div>
</td>
<td style="background: #F2F2F2; border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">3<o:p></o:p></span></b></div>
</td>
<td style="background: #F2F2F2; border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">2<o:p></o:p></span></b></div>
</td>
<td style="background: #F2F2F2; border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">1<o:p></o:p></span></b></div>
</td>
</tr>
<tr>
<td colspan="2" style="border-top: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">Class<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">P/C<o:p></o:p></span></div>
</td>
<td colspan="5" style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">Tag Number<o:p></o:p></span></div>
</td>
</tr>
</tbody></table>
<div class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 6.0pt; margin-left: 0in; margin-right: 0in; margin-top: 4.8pt;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">If <b>Class</b> is set to Universal, the value is of a
type native to ASN.1 (e.g. INTEGER). The Application class is only valid for
one specific application. Context-specific depends on the context (such as
within a sequence, set or choice) and private can be defined in private
specifications.<o:p></o:p></span></div>
<table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" style="background: white; border-collapse: collapse; border: none; mso-border-alt: solid #AAAAAA .75pt; mso-yfti-tbllook: 1184;">
<tbody>
<tr>
<td colspan="3" style="background: #F2F2F2; border: none; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">Class bits in a Type identifier octet<o:p></o:p></span></b></div>
</td>
</tr>
<tr>
<td style="background: #F2F2F2; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">Class<o:p></o:p></span></b></div>
</td>
<td style="background: #F2F2F2; border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">bit 8<o:p></o:p></span></b></div>
</td>
<td style="background: #F2F2F2; border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">bit 7<o:p></o:p></span></b></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">Universal<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">0<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">0<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">Application<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">0<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">1<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">Context-specific<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">1<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">0<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">Private<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">1<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">1<o:p></o:p></span></div>
</td>
</tr>
</tbody></table>
<div class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 6.0pt; margin-left: 0in; margin-right: 0in; margin-top: 4.8pt;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">P/C</span></b><span style="font-family: Arial, sans-serif; font-size: 10pt;"> is the <b>primitive/constructed</b> bit; it
specifies whether the value is primitive, like an INTEGER, or constructed,
which means it again holds TLV values like a SET.<o:p></o:p></span></div>
<table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" style="background: white; border-collapse: collapse; border: none; mso-border-alt: solid #AAAAAA .75pt; mso-yfti-tbllook: 1184;">
<tbody>
<tr>
<td style="background: #F2F2F2; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">P/C<o:p></o:p></span></b></div>
</td>
<td style="background: #F2F2F2; border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<b><span style="font-family: Arial, sans-serif; font-size: 10pt;">bit 6<o:p></o:p></span></b></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">Primitive<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">0<o:p></o:p></span></div>
</td>
</tr>
<tr>
<td style="border-top: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">Constructed<o:p></o:p></span></div>
</td>
<td style="border-bottom: solid #AAAAAA 1.0pt; border-left: none; border-right: solid #AAAAAA 1.0pt; border-top: none; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; mso-border-top-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div align="center" class="MsoNormal" style="line-height: 14.25pt; margin-bottom: 12.0pt; margin-left: 0in; margin-right: 0in; margin-top: 12.0pt; text-align: center;">
<span style="font-family: Arial, sans-serif; font-size: 10pt;">1<o:p></o:p></span></div>
</td>
</tr>
</tbody></table>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Tag Number – specifies standard known data types<o:p></o:p></div>
<div class="MsoNormal">
>Length - 2 or more bytes(big endian encoded)<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Big Endian / Little Endian<o:p></o:p></div>
<div class="MsoNormal">
--------------------------<o:p></o:p></div>
<div class="MsoNormal">
>Byte order in a word at hardware level<o:p></o:p></div>
<div class="MsoNormal">
>BigEndian - stores most significant byte first<o:p></o:p></div>
<div class="MsoNormal">
>LittleEndian - stores the least significant byte first<o:p></o:p></div>
<div class="MsoNormal">
>MixedEndian/MiddleEndian - both big and little endians
mixed in larger words<o:p></o:p></div>
<div class="MsoNormal">
>Endianness in networking - based on which byte is sent
first; IP uses big endian<o:p></o:p></div>
<div class="MsoNormal">
------------x-------------<o:p></o:p></div>
<div class="MsoNormal">
>SNMP agent receives request on UDP port 161<o:p></o:p></div>
<div class="MsoNormal">
>Manager receives notifications on pot 162(Trap and InformRequests)<o:p></o:p></div>
<div class="MsoNormal">
>When used with Transport Layer Security or Datagram
Transport Layer Security requests are received on port 10161 and traps are sent
to port 10162.[3].<o:p></o:p></div>
<div class="MsoNormal">
>SNMPv1 introduced 5 PDUs<o:p></o:p></div>
<div class="MsoNormal">
>SNMPv2 added two more(GetBulkRequest and InformRequest)<o:p></o:p></div>
<div class="MsoNormal">
>SNMPv3 added no new PDUs<o:p></o:p></div>
<div class="MsoNormal">
All SNMP PDUs are constructed as follows:<o:p></o:p></div>
<table border="1" cellpadding="0" cellspacing="0" class="MsoNormalTable" style="background: white; border-collapse: collapse; border: none; mso-border-alt: solid #AAAAAA .75pt; mso-yfti-tbllook: 1184;">
<tbody>
<tr>
<td style="border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal">
IP header<o:p></o:p></div>
</td>
<td style="border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal">
UDP header<o:p></o:p></div>
</td>
<td style="border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal">
version<o:p></o:p></div>
</td>
<td style="border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal">
community<o:p></o:p></div>
</td>
<td style="border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal">
PDU-type<o:p></o:p></div>
</td>
<td style="border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal">
request-id<o:p></o:p></div>
</td>
<td style="border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal">
error-status<o:p></o:p></div>
</td>
<td style="border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal">
error-index<o:p></o:p></div>
</td>
<td style="border-left: none; border: solid #AAAAAA 1.0pt; mso-border-alt: solid #AAAAAA .75pt; mso-border-left-alt: solid #AAAAAA .75pt; padding: 2.4pt 2.4pt 2.4pt 2.4pt;"><div class="MsoNormal">
variable bindings<o:p></o:p></div>
</td>
</tr>
</tbody></table>
<div class="MsoNormal">
The seven SNMP protocol data units (PDUs) are as follows:<o:p></o:p></div>
<div class="MsoListParagraphCxSpFirst" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
1.<span style="font-size: 7pt;"> </span>IP
Header<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
2.<span style="font-size: 7pt;"> </span>UDP
Header<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
3.<span style="font-size: 7pt;"> </span>Version<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
4.<span style="font-size: 7pt;"> </span>Community<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
5.<span style="font-size: 7pt;"> </span>PDU
type<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
6.<span style="font-size: 7pt;"> </span>Request
id<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
7.<span style="font-size: 7pt;"> </span>Error
status<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
8.<span style="font-size: 7pt;"> </span>Error
index<o:p></o:p></div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l0 level1 lfo1; text-indent: -.25in;">
9.<span style="font-size: 7pt;"> </span>Variable
bindings<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
<b>GetRequest</b><o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
A manager-to-agent request to
retrieve the value of a variable or list of variables. Desired variables are
specified in variable bindings (values are not used). Retrieval of the specified
variable values is to be done as an atomic operation by the agent. A Response
with current values is returned.<o:p></o:p><br />
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
<b>SetRequest</b><o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
A manager-to-agent request to
change the value of a variable or list of variables. Variable bindings are
specified in the body of the request. Changes to all specified variables are to
be made as an atomic operation by the agent. A Response with (current) new
values for the variables is returned.<o:p></o:p><br />
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
<b>GetNextRequest</b><o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
A manager-to-agent request to
discover available variables and their values. Returns a Response with variable
binding for the lexicographically next variable in the MIB. The entire MIB of
an agent can be walked by iterative application of GetNextRequest starting at
OID 0. Rows of a table can be read by specifying column OIDs in the variable
bindings of the request.<o:p></o:p><br />
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
<b>GetBulkRequest</b><o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
Optimized version of
GetNextRequest. A manager-to-agent request for multiple iterations of
GetNextRequest. Returns a Response with multiple variable bindings walked from
the variable binding or bindings in the request. PDU specific non-repeaters and
max-repetitions fields are used to control response behavior. GetBulkRequest
was introduced in SNMPv2.<o:p></o:p><br />
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
<b>Response</b><o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
Returns variable bindings and
acknowledgement from agent to manager for GetRequest, SetRequest,
GetNextRequest, GetBulkRequest and InformRequest. Error reporting is provided
by error-status and error-index fields. Although it was used as a response to
both gets and sets, this PDU was called GetResponse in SNMPv1.<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
<b>Trap</b><o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
Asynchronous notification from
agent to manager. Includes current sysUpTime value, an OID identifying the type
of trap and optional variable bindings. Destination addressing for traps is
determined in an application-specific manner typically through trap
configuration variables in the MIB. The format of the trap message was changed
in SNMPv2 and the PDU was renamed SNMPv2-Trap.<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
<b>InformRequest</b><o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
Acknowledged asynchronous
notification manager to manager[4] or agent to manager. Manager-to-manager
notifications were already possible in SNMPv1 (using a Trap), but as SNMP
commonly runs over UDP where delivery is not assured and dropped packets are
not reported, delivery of a Trap was not guaranteed. InformRequest fixes this
by sending back an acknowledgement on receipt. Receiver replies with Response
parroting all information in the InformRequest. This PDU was introduced in
SNMPv2.[5]<o:p></o:p><br />
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
>SNMPv2 added party based
security to v1 but was not agreed widely, instead community based v2c became
de-facto standard as SNMPv2c<o:p></o:p><br />
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
>SNMPv2 and SNMPv1 are not compatible
with each other due to PDU format change and additional two requests in SNMPv2<o:p></o:p><br />
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
Interoperability between different
versions of SNMP -> <a href="http://tools.ietf.org/html/rfc3584">http://tools.ietf.org/html/rfc3584</a><o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
Proxy Agent: Translates between
SNMPv1 and SNMPv2<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
Bilingual NMS: Talks both SNMPv1
and SNMPv2 as per the device capability. Identifies the agent version by
examining certain basic info from the local database or device.<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
SNMPv3: Makes no changes to the
protocol except for the addition of cryptographic security; adds security and
remote configuration enhancements to SNMP; it adds encryption/confidentiality,
integrity/message integrity and authentication/source validation; <o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
Resource Indexing: Certain devices
might change indices (of the device resources) in the MIB entries between
device reboots; for such devices, NMS should re-poll the data upon receiving
cold-restart trap from the agent <o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
Security Implications:<o:p></o:p></div>
<div class="MsoListParagraphCxSpFirst" style="mso-list: l1 level1 lfo2; text-indent: -.25in;">
1.<span style="font-size: 7pt;"> </span>SNMPv1
and SNMPv2 send community string as clear text hence prone to attack using packet
sniffers<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l1 level1 lfo2; text-indent: -.25in;">
2.<span style="font-size: 7pt;"> </span>All
versions of SNMP are subject to brute force and dictionary attacks for guessing
the community strings, authentication strings, authentication keys, encryption
strings, or encryption keys, because they do not implement a challenge-response
handshake.<o:p></o:p></div>
<div class="MsoListParagraphCxSpMiddle" style="mso-list: l1 level1 lfo2; text-indent: -.25in;">
3.<span style="font-size: 7pt;"> </span>Although
SNMP works over TCP and other protocols, it is most commonly used over UDP that
is connectionless and vulnerable to IP spoofing attacks. Thus, all versions are
subject to bypassing device access lists that might have been implemented to
restrict SNMP access, though SNMPv3's other security mechanisms should prevent
a successful attack.<o:p></o:p></div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l1 level1 lfo2; text-indent: -.25in;">
4.<span style="font-size: 7pt;"> </span>Auto
Discovery – trying to discover local network devices by broadcasting community
strings might pose security threat in a shared data centers or commercial
networks<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
SMIv1 – used by SNMPv1<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
SMIv2 – used by SNMPv2 and SNMPv3<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
>SNMP is an internet standard
protocol<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
>SGMP(Simple Gateway Management
Protocol) is the predecessor to SNMP<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
>Host Resources MIB implements
disk space , running processes and such things on Windows or Linux system<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
>An agent usually implements
multiple MIBs; from standard MIBs to proprietary MIBs<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
>MIB-II defines standard
management information and interface details for a typical device<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
>RMON – Remote Monitoring; data
collector for a network without NMS; NMS can later poll the RMON probe data
collector to retrieve complete management polled data for the remote network;
RMON probe can also send traps to NMS upon certain critical condition on
monitored network<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
>Some standard MIBs: ATM MIB,
Frame Relay DTE Interface Type MIB, BGP MIB, RDBMS MIB, Radius Auth Server MIB,
Mail Monitoring MIB, DNS Server MIB<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
>SMI(Structure of Management
Information) tells how to define managed objects and properties <o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
>MIB is a definition of
management data for a device using SMI notations<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
>Network Management mainly
focuses on FCAPS(defined by ISO)<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
>FCAPS: Fault, Configuration,
Accounting, Performance, Security<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
Fault Management: detect, log and
report faults in the devices and networks; 1)isolate the problem;<br />
<br />
2)resolve the
problem, 3)record the process used to detect and resolve the problems<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
Configuration Management: Monitor
and Change certain information in devices that would change the behavior of the
device in some way.<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
Accounting Management: Tracking
network resource utilization by all groups and individuals to ensure fair usage
and capacity sharing<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
Performance Management: 1.
Performance data is gathered, 2. Baseline levels are established based on data
gathered, 3. Performance thresholds are established, and when the thresholds
are exceeded, alert is raised to indicate the problems.<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
Security Management: 1. Control
access to resources such as devices, services and networks, 2. Detect and
prevent attacks that can compromise networks and hosts. Not only network
security but also physical security; todays security tools and systems are:- 1.
Firewalls, 2. Intrusion Detection Systems(IDS), 3. Intrusion Prevention
Systems(IPS), 4. Antivirus Systems, 5. Policy Management and Enforcement
System.<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
Most of today’s network security
systems can integrate with NMS through SNMP.<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br />
Alarm Correlation or RCA(Root
Cause Analysis): Alarm correlation deals with narrowing down many alerts and
events into a single alert or several events that depict the real problem.<o:p></o:p></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br /></div>
<div class="MsoNormal" style="margin-left: .25in;">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-CnSemibold, sans-serif;"><span style="font-size: x-small;"><b>Getting More Information</b></span><span style="font-size: large;"><o:p></o:p></span></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Getting a
handle on SNMP may seem like a daunting task. The RFCs provide the<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">official
definition of the protocol, but they were written for software developers, not<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">network
administrators, so it can be difficult to extract the information you need<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">from them.
Fortunately, many online resources are available. A good place to look is<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">the SimpleWeb
(</span><i><span style="font-family: Birka-Italic; font-size: 10pt;"><a href="http://www.simpleweb.org/">http://www.simpleweb.org</a></span></i><span style="font-family: Birka; font-size: 10pt;">). SNMP Link (</span><i><span style="font-family: Birka-Italic; font-size: 10pt;"><a href="http://www.snmplink.org/">http://www.SNMPLink.org</a></span></i><span style="font-family: Birka; font-size: 10pt;">)<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">is another
good site for information. </span><i><span style="font-family: Birka-Italic; font-size: 10pt;">The Simple Times</span></i><span style="font-family: Birka; font-size: 10pt;">, an online publication<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">devoted to SNMP
and network management, is also useful. You can find all the<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">issues ever
published</span><span style="font-family: Birka; font-size: 7.5pt;">* </span><span style="font-family: Birka; font-size: 10pt;">at </span><i><span style="font-family: Birka-Italic; font-size: 10pt;"><a href="http://www.simple-times.org/">http://www.simple-times.org</a></span></i><span style="font-family: Birka; font-size: 10pt;">. SNMP Research is a commercial<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">SNMP vendor.
Aside from selling advanced SNMP solutions, its web site contains<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">a good amount
of free information about SNMP. The company’s web site is<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 10pt;"><a href="http://www.snmp.com/">http://www.snmp.com</a></span></i><span style="font-family: Birka; font-size: 10pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 8pt;">* At this
writing, the current issue is quite old, published in December 2002.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="color: white; font-family: Birka-Italic; font-size: 9pt;">This is the Title of the Book, eMatter Edition<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="color: white; font-family: Birka-Italic; font-size: 9pt;">Copyright © 2008 O’Reilly & Associates, Inc. All rights
reserved.<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 9pt;"><b>18 | Chapter 1: Introduction to SNMP and Network Management</b><o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Another great
resource is Usenet news. The newsgroup most people frequent is<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 10pt;">comp.dcom.net-management</span></i><span style="font-family: Birka; font-size: 10pt;">. Another good
newsgroup is </span><i><span style="font-family: Birka-Italic; font-size: 10pt;">comp.protocols.snmp</span></i><span style="font-family: Birka; font-size: 10pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Groups such as
these promote a community of information sharing, allowing seasoned<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">professionals
to interact with individuals who are not as knowledgeable about<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">SNMP or
network management. Google has a great interface for searching Usenet<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">news group at </span><i><span style="font-family: Birka-Italic; font-size: 10pt;"><a href="http://groups.google.com/">http://groups.google.com</a></span></i><span style="font-family: Birka; font-size: 10pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">There is an
SNMP FAQ, available in two parts at </span><i><span style="font-family: Birka-Italic; font-size: 10pt;"><a href="http://www.faqs.org/faqs/snmp-faq/part1" target="_blank">http://www.faqs.org/faqs/snmp-faq/part1</a>/ </span></i><span style="font-family: Birka; font-size: 10pt;">and </span><i><span style="font-family: Birka-Italic; font-size: 10pt;"><a href="http://www.faqs.org/faqs/snmp-faq/part2/">http://www.faqs.org/faqs/snmp-faq/part2/</a></span></i><span style="font-family: Birka; font-size: 10pt;">.</span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Cisco has some
very good papers on network management, including “Network<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Management
Basics” (</span><a href="http://www.cisco.com/univercd/cc/td/doc/cisintwk/ito_doc/nmbasics.htm"><i><span style="font-family: Birka-Italic; font-size: 10pt;">http://www.cisco.com/univercd/cc/td/doc/cisintwk/ito_doc/</span></i><i><span style="font-family: Birka-Italic; font-size: 10pt;">nmbasics.htm</span></i></a><span style="font-family: Birka; font-size: 10pt;">) and “Change Management,” from
which Figure 1-2 and Figure 1-3</span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">were drawn.
Also, Douglas W. Stevenson’s article, “Network Management: What It<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Is and What It
Isn’t,” available at </span><i><span style="font-family: Birka-Italic; font-size: 10pt;"><a href="http://www.itmweb.com/essay516.htm">http://www.itmweb.com/essay516.htm</a></span></i><span style="font-family: Birka; font-size: 10pt;">,</span><span style="font-family: Birka; font-size: 10pt;"> provides<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-left: .25in;">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">important
background material for all students of network management.<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">>SNMP uses UDP<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">>UDP is defined in RFC 768<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">>UDP was chosen over TCP(Transmission
Control Protocol) because it is connectionless.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">>Hence, an NMS should resend the datagram
after a timeout assuming it is lost in the transit. No.of retries is
configurable<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">>SNMP is an application layer protocol<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">>Due to this unreliable UDP, NMS may not
get traps sometimes from agents, if the trap datagram is lost in between<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">>At the same time, the unreliable UDP puts
less load on the network performance<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">>SNMP has been implemented<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">over TCP, but this is more for special-case
situations in which someone is developing<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">an agent for a proprietary piece of
equipment. In a heavily congested and managed<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">network, SNMP over TCP is a bad idea. It’s
also worth realizing that TCP isn’t<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">magic and that SNMP is designed for working
with networks that are in trouble—if<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">your network never failed, you wouldn’t need
to monitor it. When a network is failing,<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">a protocol that tries to get the data through
but gives up if it can’t is almost certainly<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">a better design choice than a protocol that
floods the network with<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">retransmissions in its attempt to achieve
reliability.<o:p></o:p></span></div>
<div class="MsoNormal">
<br />
>>SNMP community modes: read-only, read-write and trap
communities<o:p></o:p></div>
<div class="MsoNormal">
>Among other things, authentication-failure traps can be
very useful in determining when an intruder might be trying to gain access to
your network.<o:p></o:p></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<br />
><span style="font-family: Birka; font-size: 10pt;">The definition of managed objects can be broken down into three
attributes:<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 10pt;">Name<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">The name, or
object identifier (OID), uniquely defines a managed object. Names<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">commonly
appear in two forms: numeric and “human readable.” In either case,<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">the names are
long and inconvenient. In SNMP applications, a lot of work goes<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">into helping
you navigate through the namespace conveniently.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 10pt;">Type and syntax<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">A managed
object’s datatype is defined using a subset of Abstract Syntax Notation<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">One (ASN.1).
ASN.1 is a way of specifying how data is represented and<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">transmitted
between managers and agents, within the context of SNMP. The<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">nice thing
about ASN.1is that the notation is machine independent. This means<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">that a PC
running Windows 2000 can communicate with a Sun SPARC machine<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">and not have
to worry about things such as byte ordering.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="color: white; font-family: Birka-Italic; font-size: 9pt;">This is the Title of the Book, eMatter Edition<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 10pt;">Encoding<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">A single
instance of a managed object is encoded into a string of octets using<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">the Basic
Encoding Rules (BER). BER defines how the objects are encoded and<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">decoded so
that they can be transmitted over a transport medium such as<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">Ethernet.</span><o:p></o:p></div>
<div class="MsoNormal">
<br />
>1.3.6.1 – internet OID<o:p></o:p></div>
<div class="MsoNormal">
<br />
>private enterprises space, e.g <i><span style="font-family: Birka-Italic; font-size: 10pt; line-height: 115%;">iso.org.dod.internet.private.enterprises.cisco</span></i><span style="font-family: Birka; font-size: 10pt; line-height: 115%;">, or </span><i><span style="font-family: Birka-Italic; font-size: 10pt; line-height: 115%;">1.3.6.1.4.1.9</span></i><span style="font-family: Birka; font-size: 10pt; line-height: 115%;">.<o:p></o:p></span></div>
<div class="MsoNormal">
OID and data types<o:p></o:p></div>
<div class="MsoNormal">
<br />
-------------------------<o:p></o:p></div>
<div class="MsoNormal">
>IpAddress represents 32bit value (both SMIv1 and SMIv2
do not talk about IPv6 addressing)<o:p></o:p></div>
<div class="MsoNormal">
>Gauge moves between min and max value but never exceeds
max(interface speed)<o:p></o:p></div>
<div class="MsoNormal">
>Counter – ever increasing count tracker, can wrap around
and start over from 0<o:p></o:p></div>
<div class="MsoNormal">
>OBJECT IDENTIFIER represents a MIB Object<o:p></o:p></div>
<div class="MsoNormal">
>TimeTicks – represents time to .01sec precision<o:p></o:p></div>
<div class="MsoNormal">
>Opaque Allows any other ASN.1 encoding to be stuffed
into an OCTET STRING.<o:p></o:p></div>
<div class="MsoNormal">
>SEQUENCE Defines lists that contain zero or more other
ASN.1 datatypes.<o:p></o:p></div>
<div class="MsoNormal">
SEQUENCE OF Defines a managed object that is made up of a
SEQUENCE of ASN.1 types.<o:p></o:p></div>
<div class="MsoNormal">
<br />
>MIB is a logical grouping of managed objects as they
pertain to a specific management<o:p></o:p></div>
<div class="MsoNormal">
task, vendor, etc. The MIB can be thought of as a
specification that defines<o:p></o:p></div>
<div class="MsoNormal">
the managed objects a vendor or device supports.<o:p></o:p></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
><span style="font-family: Birka; font-size: 10pt;">After the OIDs are defined, we get to the actual object
definitions. Every object definition<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">has the
following format:<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><name> OBJECT-TYPE<o:p></o:p></name></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">SYNTAX <datatype><o:p></o:p></datatype></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">ACCESS <either not-accessible="" or="" read-only,="" read-write,="" write-only,=""><o:p></o:p></either></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">STATUS <either mandatory,="" obsolete="" optional,="" or=""><o:p></o:p></either></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">DESCRIPTION<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">"Textual description describing this particular managed object."<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">::= { <unique defines="" object="" oid="" that="" this=""> }<o:p></o:p></unique></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;"><br /></span><br />
<span style="font-family: Birka; font-size: 10pt;">The first
managed object in our subset of the MIB-II definition is </span><i><span style="font-family: Birka-Italic; font-size: 10pt;">ifTable</span></i><span style="font-family: Birka; font-size: 10pt;">, which represents<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">a table of
network interfaces on a managed device (note that object names are<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">defined using
mixed case, with the first letter in lowercase). Here is its definition<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">using ASN.1
notation:<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="color: white; font-family: Birka-Italic; font-size: 9pt;">This is the Title of the Book, eMatter Edition<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="color: white; font-family: Birka-Italic; font-size: 9pt;">Copyright © 2008 O’Reilly & Associates, Inc. All rights
reserved.<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">ifTable OBJECT-TYPE<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">SYNTAX SEQUENCE OF IfEntry<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">ACCESS not-accessible<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">STATUS mandatory<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">DESCRIPTION<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">"A list of interface entries. The number of entries is given
by<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">the value of ifNumber."<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">::= { interfaces 2 }<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;"><br /></span><br />
<span style="font-family: Birka; font-size: 10pt;">The </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 9pt;">SYNTAX </span><span style="font-family: Birka; font-size: 10pt;">of </span><i><span style="font-family: Birka-Italic; font-size: 10pt;">ifTable </span></i><span style="font-family: Birka; font-size: 10pt;">is </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 9pt;">SEQUENCE OF
IfEntry</span><span style="font-family: Birka; font-size: 10pt;">. This means that </span><i><span style="font-family: Birka-Italic; font-size: 10pt;">ifTable
</span></i><span style="font-family: Birka; font-size: 10pt;">is a table containing<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">the columns
defined in </span><i><span style="font-family: Birka-Italic; font-size: 10pt;">IfEntry</span></i><span style="font-family: Birka; font-size: 10pt;">. The object is </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 9pt;">not-accessible</span><span style="font-family: Birka; font-size: 10pt;">, which means<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">that there is
no way to query an agent for this object’s value. Its status is </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 9pt;">mandatory</span><span style="font-family: Birka; font-size: 10pt;">,<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">which means an
agent must implement this object in order to comply with the MIBII<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">specification.
The </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 9pt;">DESCRIPTION </span><span style="font-family: Birka; font-size: 10pt;">describes exactly what this object is. The unique<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">OID is </span><i><span style="font-family: Birka-Italic; font-size: 10pt;">1.3.6.1.2.1.2.2</span></i><span style="font-family: Birka; font-size: 10pt;">, or </span><i><span style="font-family: Birka-Italic; font-size: 10pt;">iso.org.dod.internet.mgmt.mib-2.interfaces.2</span></i><span style="font-family: Birka; font-size: 10pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Let’s now look
at the </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 9pt;">SEQUENCE </span><span style="font-family: Birka; font-size: 10pt;">definition from the MIB file earlier in this section,<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt; line-height: 115%;">which is used with the </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 9pt; line-height: 115%;">SEQUENCE OF </span><span style="font-family: Birka; font-size: 10pt; line-height: 115%;">type in the </span><i><span style="font-family: Birka-Italic; font-size: 10pt; line-height: 115%;">ifTable </span></i><span style="font-family: Birka; font-size: 10pt; line-height: 115%;">definition:</span><o:p></o:p></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">IfEntry
::=<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">SEQUENCE
{<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">ifIndex<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">INTEGER,<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">ifDescr<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">DisplayString,<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">ifType<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">INTEGER,<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">ifMtu<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">INTEGER,<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">ifSpecific<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">OBJECT
IDENTIFIER<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt; line-height: 115%;">}<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 9pt;"><br /></span></i><br />
<i><span style="font-family: Birka-Italic; font-size: 9pt;"><br /></span></i><br />
<i><span style="font-family: Birka-Italic; font-size: 9pt;">Table
2-2. New datatypes for SMIv2<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 9pt;">------------------------------------------------<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 9pt;">Datatype
Description<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Integer32
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Same as an </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">INTEGER</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Counter32
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Same as a </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Counter</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Gauge32
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Same as a </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Gauge</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Unsigned32
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Represents decimal values in the range
of 0 to 2</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 7pt;">32 </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">-
1, inclusive.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Counter64
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Similar to </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Counter32</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">,
but its maximum value is 18,446,744,073,709,551,615. </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Counter64 </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">is
ideal<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">for
situations in which a </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Counter32 </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">may wrap back to 0 in a short amount of time.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt; line-height: 115%;">BITS
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt; line-height: 115%;">An enumeration of nonnegative named
bits.<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 9pt;">Table 2-5. Brief description of the MIB-II groups<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 9pt;">Subtree name OID Description<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">system </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">1.3.6.1.2.1.1 </span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Defines a list of objects that pertain to system
operation, such as the system<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">uptime, system contact, and system name.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">interfaces </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">1.3.6.1.2.1.2
</span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Keeps track of the status of
each interface on a managed entity. The </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">interfaces<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">group monitors which interfaces are up or down and tracks such
things as octets<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">sent and received, errors and discards, etc.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">at </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">1.3.6.1.2.1.3 </span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">The address translation (</span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">at</span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">) group is deprecated and is provided only for backward<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">compatibility.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">ip </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">1.3.6.1.2.1.4 </span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Keeps track of many aspects of IP, including IP
routing.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">icmp </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">1.3.6.1.2.1.5 </span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Tracks things such as ICMP errors, discards, etc.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">tcp </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">1.3.6.1.2.1.6 </span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Tracks, among other things, the state of the TCP
connection (e.g., </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">closed</span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">, </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">listen</span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">,<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">synSent</span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">, etc.).<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">udp </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">1.3.6.1.2.1.7 </span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Tracks UDP statistics, datagrams in and out, etc.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 8pt;">Root-Node<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 8pt;">ccitt(0) iso(1) joint(2)<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 8pt;">org(3)<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 8pt;">dod(6)<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 8pt;">internet(1)<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 8pt;">directory(1) mgmt(2) experimental(3) private(4)<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 8pt;">mib-2(1)<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 8pt;">system(1) interfaces(2) at(3) ip(4) icmp(5) tcp(6) udp(7) egp(8)
transmission(10) snmp(11)<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="color: white; font-family: Birka-Italic; font-size: 9pt;">This is the Title of the Book, eMatter Edition<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="color: white; font-family: Birka-Italic; font-size: 9pt;">Copyright © 2008 O’Reilly & Associates, Inc. All rights
reserved.<o:p></o:p></span></i></div>
<div class="MsoNormal">
>snmpwalk is nothing but a form of snmpgetnext command<o:p></o:p></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 9pt;"><br /></span></i><br />
<i><span style="font-family: Birka-Italic; font-size: 9pt;">Table 2-8. Generic traps<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 9pt;">Generic trap name and number Definition<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">coldStart (0) </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Indicates that the agent has rebooted. All management variables
will be reset;<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">specifically, </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Counter</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">s and </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">Gauge</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">s will be reset to zero (0). One nice thing about<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">the </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">coldStart </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">trap is that it can be used to determine when new
hardware is<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">added to the network. When a device is powered on, it sends this
trap to its trap<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">destination. If the trap destination is set correctly (i.e., to
the IP address of your<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">NMS), the NMS can receive the trap and determine whether it needs
to manage<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">the device.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">warmStart (1) </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Indicates that the agent has reinitialized itself. None of the
management variables<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">will be reset.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">linkDown (2) </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Sent when an interface on a
device goes down. The first variable binding identifies<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">the index in the </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">interfaces </span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">table for the interface that went down.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">linkUp
(3) </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Sent when an interface on a device comes
back up. The first variable binding identifies<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">which
interface came back up.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">authenticationFailure
(4) </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Indicates that someone has tried to
query your agent with an incorrect community<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">string;
useful in determining if someone is trying to gain unauthorized access to<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">one
of your devices.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">egpNeighborLoss
(5) </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Indicates that an EGP neighbor has gone
down.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<br /></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">enterpriseSpecific
(6) </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Indicates that the trap is
enterprise-specific. SNMP vendors and users define their<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">own
traps under the </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">private-enterprise </span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">branch of the SMI </span><i><span style="font-family: Myriad-CnItalic, sans-serif; font-size: 9pt;">object
</span></i><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">tree. To process<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">this
trap properly, the NMS has to decode the specific trap number that is part of<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">the
SNMP message.</span><i><span style="color: white; font-family: Birka-Italic; font-size: 9pt;">This is the Title of the Book,
eMatter Edition<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="color: white; font-family: Birka-Italic; font-size: 9pt;">Copyright © 2008 O’Reilly & Associates, Inc. All rights
reserved.<o:p></o:p></span></i></div>
<div class="MsoNormal">
--<o:p></o:p></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">RDBMS MIB. One of the
traps<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">defined by this MIB is </span><i><span style="font-family: Birka-Italic; font-size: 10pt;">rdbmsOutOfSpace</span></i><span style="font-family: Birka; font-size: 10pt;">:<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">rdbmsOutOfSpace
TRAP-TYPE<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">ENTERPRISE
rdbmsTraps<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">VARIABLES
{ rdbmsSrvInfoDiskOutOfSpaces }<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">DESCRIPTION<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">"An
rdbmsOutOfSpace trap signifies that one of the database<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">servers
managed by this agent has been unable to allocate<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">space
for one of the databases managed by this agent. Care<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">should
be taken to avoid flooding the network with these traps."<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt; line-height: 115%;">::=
2<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt; line-height: 115%;">--<o:p></o:p></span></div>
<div class="MsoNormal">
<br />
The most important change is that Version 3 abandons the
notion of managers and<o:p></o:p></div>
<div class="MsoNormal">
agents. Both managers and agents are now called SNMP
entities. Each entity consists<o:p></o:p></div>
<div class="MsoNormal">
of an SNMP engine and one or more SNMP applications, which
are discussed in<o:p></o:p></div>
<div class="MsoNormal">
the following sections. These new concepts are important
because they define an<o:p></o:p></div>
<div class="MsoNormal">
architecture rather than simply a set of messages; the
architecture helps to separate<o:p></o:p></div>
<div class="MsoNormal">
different pieces of the SNMP system in a way that makes a
secure implementation<o:p></o:p></div>
<div class="MsoNormal">
possible.<o:p></o:p></div>
<div class="MsoNormal">
--<o:p></o:p></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 15pt;"><br /></span><br />
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 15pt;">The
SNMPv3 Engine<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">The engine is composed of
four pieces: the Dispatcher, the Message Processing Subsystem,<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">the Security Subsystem,
and the Access Control Subsystem. The Dispatcher’s<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">job is to send and receive
messages. It tries to determine the version of each<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">received message (i.e.,
v1, v2, or v3) and, if the version is supported, hands the message<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">off to the Message
Processing Subsystem. The Dispatcher also sends SNMP<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">messages to other
entities.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;"><br /></span><br />
<span style="font-family: Birka; font-size: 10pt;">The Message Processing
Subsystem prepares messages to be sent and extracts data<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">from received messages. A
Message Processing Subsystem can contain multiple message<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">processing modules. For
example, a subsystem can have modules for processing<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">SNMPv1, SNMPv2, and SNMPv3
requests. It may also contain a module for<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">other processing models
that are yet to be defined.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;"><br /></span><br />
<span style="font-family: Birka; font-size: 10pt;">The Security Subsystem
provides authentication and privacy services. Authentication<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">uses either community
strings (SNMP v1and v2) or SNMPv3 user-based<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt;">authentication. User-based
authentication uses the MD5 or SHA algorithms to<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">authenticate users without
sending a password in the clear. The privacy service uses<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">the DES algorithm to
encrypt and decrypt SNMP messages. Currently, DES is the<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">only algorithm used,
though others may be added in the future.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;"><br /></span><br />
<span style="font-family: Birka; font-size: 10pt;">The Access Control
Subsystem is responsible for controlling access to MIB objects.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">You can control what
objects a user can access as well what operations she is<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">allowed to perform on
those objects. For example, you might want to limit a user’s<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">read-write access to
certain parts of the </span><i><span style="font-family: Birka-Italic; font-size: 10pt;">mib-2 </span></i><span style="font-family: Birka; font-size: 10pt;">tree while allowing
read-only access to<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt;">the entire tree.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 15pt;"><br /></span><br />
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 15pt;">SNMPv3
Applications<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Version 3 divides most of
what we have come to think of as SNMP into a number of<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">applications:<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 10pt;"><br /></span></i><br />
<i><span style="font-family: Birka-Italic; font-size: 10pt;">Command
generator<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Generates get, getnext,
getbulk, and set requests and processes the responses.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">This application is
implemented by an NMS, so it can issue queries and set<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">requests against entities
on routers, switches, Unix hosts, etc.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 10pt;"><br /></span></i><br />
<i><span style="font-family: Birka-Italic; font-size: 10pt;">Command
responder<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Responds to get, getnext,
getbulk, and set requests. This application is implemented<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">by an entity on a Cisco
router or Unix host. (For versions 1and 2, the<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">command responder is
implemented by the SNMP agent.)<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 10pt;"><br /></span></i><br />
<i><span style="font-family: Birka-Italic; font-size: 10pt;">Notification
originator<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Generates SNMP traps and
notifications. This application is implemented by an<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">entity on a router or Unix
host. (For versions 1and 2, the notification originator<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">is part of an SNMP agent.
Freestanding utilities for generating traps are also<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">available.)<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 10pt;"><br /></span></i><br />
<i><span style="font-family: Birka-Italic; font-size: 10pt;">Notification
receiver<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">Receives traps and inform
messages. This application is implemented by an<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">NMS.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 10pt;"><br /></span></i><br />
<i><span style="font-family: Birka-Italic; font-size: 10pt;">Proxy
forwarder<o:p></o:p></span></i></div>
<div class="MsoNormal">
<span style="font-family: Birka; font-size: 10pt;">Facilitates message passing
between entities.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 15pt;"><br /></span><br />
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 15pt;"><br /></span><br />
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 15pt;">SNMPv3
Textual Conventions<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;">SNMPv3 defines a number of
additional textual conventions, outlined in Table 3-2.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Birka; font-size: 10pt;"><br /></span><br />
<span style="font-family: Birka; font-size: 10pt;">The next two sections will
look at the USM and VACM in a little more detail.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 9pt;"><br /></span></i><br />
<i><span style="font-family: Birka-Italic; font-size: 9pt;">Figure
3-1. SNMPv3 entity<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<i><span style="font-family: Birka-Italic; font-size: 9pt;">Table
3-2. SNMPv3 textual conventions<o:p></o:p></span></i></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 9pt;"><br /></span><br />
<span style="font-family: Myriad-CnSemibold, sans-serif; font-size: 9pt;">Textual
convention Description<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">snmpEngineID
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">An administratively unique identifier
for an SNMP engine. Objects of this type<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">are
for identification, not for addressing, even though an address can be used in<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">the
generation of a specific value. RFC 3411 provides a detailed discussion of<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">how
</span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">snmpEngineID</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">s are created.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">snmpSecurityModel
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">An SNMP </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">securityModel
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">(SNMPv1, SNMPv2, or USM). USM stands for
Userbased<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">Security
Model, which is the security method used in SNMPv3.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">snmpMessageProcessingModel
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">A message processing model used by the
Message Processing Subsystem.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">snmpSecurityLevel
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">The level of security at which SNMP
messages can be sent, or the level of security<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">at
which operations are being processed. Possible values are<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">noAuthNoPriv
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">(without authentication and without
privacy), </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">authNoPriv<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">(with
authentication but without privacy), and </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">authPriv
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">(with authentication<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">and
with privacy). These three values are ordered such that<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">noAuthNoPriv
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">is less than </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">authNoPriv </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">and
</span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">authNoPriv </span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">is less than<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">authPriv</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">snmpAdminString
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">An octet string containing administrative
information, preferably in humanreadable<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">form.
The string can be up to 255 bytes long.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">snmpTagValue
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">An octet string containing a tag value.
Tag values are preferably in human-readable<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">form.
According to RFC 3413, valid example tags include </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">acme</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">,
</span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">router</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">,<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">and
</span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">host</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">.<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">snmpTagList
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">An octet string containing a list of tag
values. Tag values are preferably in<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">human-readable
form. According to RFC 3413, valid examples of a tag list are<o:p></o:p></span></div>
<div class="MsoNormal" style="margin-bottom: 0.0001pt;">
<span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">the
empty string, </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">acme router</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">, and </span><span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">host managerStation</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;"><br /></span><br />
<span style="font-family: TheSansMonoCondensed-SemiLight; font-size: 8pt;">KeyChange
</span><span style="font-family: Myriad-Condensed, sans-serif; font-size: 9pt;">An object used to change authentication
and privacy keys.<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
------------------x---------------x--------------<o:p></o:p></div>
<div class="MsoNormal">
<br />
Network Technology<o:p></o:p></div>
<div class="MsoNormal">
<br />
Network nodes: switches, bridges, routers or gateways<o:p></o:p></div>
<div class="MsoNormal">
<br />
Network Links: Local Area
Network(LAN), Wide Area Network(WAN), Access Networks, Customer<br />
Premises
Equipment(CPE)/Home Networks<o:p></o:p></div>
<div class="MsoNormal">
<br />
Fiber Distributed Data Interface
(FDDI) – Token Ring based architecture in fiber optic environment<o:p></o:p></div>
<div class="MsoNormal">
<br />
VLAN – virtual LAN<o:p></o:p></div>
<div class="MsoNormal">
<br />
WLAN – wireless LAN<o:p></o:p></div>
<div class="MsoNormal">
<br />
DTE – Data Terminal Equipment<o:p></o:p></div>
<div class="MsoNormal">
<br />
LAN configured in: bus, ring,
star topologies<o:p></o:p></div>
<div class="MsoNormal">
<br />
Hub – is a pseudo topology that
combines a star topology with either of the other two<o:p></o:p></div>
<div class="MsoNormal">
Star topology is used for hub
implementations or for WLAN using an access point (AP)<o:p></o:p></div>
<div class="MsoNormal">
<br />
DTE – each device that is
connected in a LAN<o:p></o:p></div>
<div class="MsoNormal">
<br />
WAN – uses either mesh or tree
topology<o:p></o:p></div>
<div class="MsoNormal">
<br />
Mesh topology – is most common
form for Internet routing<o:p></o:p></div>
<div class="MsoNormal">
Tree topology is employed using
brouters.<o:p></o:p></div>
<div class="MsoNormal">
<br />
Brouters – bridged routers that
do the routing function at OSI layer 2(also known as spanning tree
configuration)<o:p></o:p></div>
<div class="MsoNormal">
<br />
Ethernet is specified by IEEE
802.3 standard.<o:p></o:p></div>
<div class="MsoNormal">
<br />
IBM uses Token-Ring.<o:p></o:p></div>
<div class="MsoNormal">
<br />
Token-Ring: Whoever holds the
token can transmit data. After done with token, it passes to the downstream
neighbor thus creating round-robin situation. Hence Token ring is bandwidth
efficient<o:p></o:p></div>
<div class="MsoNormal">
<br />
Flooding – a node receiving the
same packet multiple times<o:p></o:p></div>
<div class="MsoNormal">
<br />
Looping – a packet going around
nodes in a loop<o:p></o:p></div>
<div class="MsoNormal">
<br />
Mesh topology is implemented
using switches and routers.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
>>SNMPv1 get/set PDU<o:p></o:p></div>
<div class="MsoNormal">
<br />
PDUType|RequestID|ErrorStatus|ErrorIndex|Varbind1
Name|Varbind1 Value|…..|Varbindn Name|Varbindn Value|<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
>>SNMPv1 Trap PDU<o:p></o:p></div>
<div class="MsoNormal">
<br />
PDUType|enterprise|agent
IP|Speficif Trap Type|Generic Trap Type|TimeStamp|Varbinds…..<o:p></o:p></div>
<div class="MsoNormal">
<br />
>>SNMPv2 doesn’t have
separate PDU for traps. It unified all PDUs into one format except for<br />
<br />
SNMPBulk
request which is also a new PDU introduced in SNMPv2<o:p></o:p></div>
<div class="MsoNormal">
<br />
>>SNMPv2
get/set/trap/inform/getnext/getresponse PDU format(for trap PDU, varbind1 has<br />
sysUpTime and varbind2 has snmpTrapOID)<o:p></o:p></div>
<div class="MsoNormal">
<br />
PDUType|RequestID|ErrorStatus|ErrorIndex|varbinds…..<o:p></o:p></div>
<div class="MsoNormal">
<br />
>>SNMPv2 GetBulk PDU format<o:p></o:p></div>
<div class="MsoNormal">
<br />
PDUType|RequestID|NonRepeaters|MaxRepetitions|varbinds…<o:p></o:p></div>
<div class="MsoNormal">
<br />
>>ErrorIndex – tells you
which varbind caused the error<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
</div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-7719915143280395742012-06-07T07:56:00.000+05:302012-07-17T23:17:45.387+05:30GIST NOTES 21 - Swing<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 21 - Swing</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books/sources on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<b><span style="color: blue;">Note - This one is incomplete at the moment</span></b><br />
<br />
<br />
-------------------------------------|<br />
FILTHY RICH CLIENTS 2007 - GUI BASICS|<br />
-------------------------------------|<br />
Web Clients: complete-send-process-return-display application model.<br />
Rich Clients: very “rich” user experience, taking advantage of<br />
native facilities of the user’s desktop computer, such as graphics hardware<br />
acceleration, to provide a more robust and full-featured application experience<br />
than is provided by Web clients. Rich client applications can sometimes<br />
take longer to start up than a simple Web page because there is more going<br />
on in the application, and the GUIs tend to be more involved than Web GUIs<br />
because there is more happening in the application than in simple Weboriented<br />
applications. The interaction model is quite different because much<br />
of the logic of the application is local, even if the application is talking to a<br />
server on the back end.<br />
<br />
New Model: AJAX - Lately, a new model has emerged for Web clients, called Asynchronous Java-<br />
Script and XML (AJAX), where much of the client-server interaction can be<br />
handled in parallel with the user’s interacting with each Web page. This transparent<br />
client-server interaction can allow for dynamically updated Web pages<br />
instead of the more tedious complete-send-process-return-display model of traditional<br />
Web client applications. However, this model is still limited by the<br />
browser container in which the application lives and by many of the constraints<br />
that that browser model places on the application, including the extent to which<br />
JavaScript features are supported, the security model of the browser, and the<br />
physical GUI of the browser container around the application.<br />
<br />
>AWT was the only GUI toolkit shipped with JDK 1.0 and still available as it is<br />
>AWT builds on top of platform windows<br />
>AWT has become an essential infrastructure piece that Swing depends on<br />
>Swing provides more flexible and powerful GUI development environment than AWT<br />
>AWT provides windowing, event mechanism, cut and paste, drag and drop, key board focus management, and input management<br />
>AWT and Java 2D sit on Java Runtime; both are independent components; Swing sits on top of both AWT and Java 2D<br />
>Java 2D: Is the graphics library of java<br />
>AWT just provides basic drawing capabilities; Java 2D provides covers basics, broad set of drawing operations, advanced drawing operations, image manipulation, text and printing<br />
>Swing uses Java 2D to render itself<br />
>Both Java 2D and Swing were introduced in JDK 1.2<br />
>Swing is a lightweight toolkit; except for toplevel windows all swing components are drawn using Java 2D and they do not correspond to native components as the case of AWT components<br />
>AWT and Java 2D underlie Swing<br />
<br />
• Events: The way that Swing receives and processes events is key to understanding<br />
how threads interact within Swing and how your application<br />
threads interact with Swing and AWT events.<br />
• Painting: Swing painting is the process by which Swing manages application<br />
and system requests to update the display.<br />
• Rendering: Swing rendering is the process by which Swing calls its own<br />
internal code as well as your application code in order to render components’<br />
contents.<br />
• Double-Buffering: Swing uses a back buffer to ensure smooth updates to<br />
the screen.<br />
• Threading: The Event mechanism is explored in more detail, and ways of<br />
interacting effectively with the Swing GUI thread are examined.<br />
<br />
>Painting vs Rendering : You render GUI before you paint it on a graphics device<br />
<br />
>Events can come from native system(window becoming visible, keyboard input, etc) or from java itself(application spawned requests)<br />
>All events are queued; java.awt.EventQueue object is responsible for dispatching these events; a single thread called EDT(event dispatch thread) serves all these events<br />
>Painting process, system events related to GUI, application tasks modifying the GUI are all processed by EDT<br />
<br />
Swing Painting<br />
--------------<br />
>Painting in Swing is the process by which your application updates the display.<br />
>The process consists of a paint request being posted onto the event queue and results in calls to the paint() and paintComponent() methods on the EDT for each Swing component affected.<br />
>Painting requests originate in one of two ways: The Swing or AWT libraries<br />
themselves may post a repaint request, or the application code may post such a<br />
request. Swing and AWT request a repaint in response to some event in the<br />
native system or the GUI components. For example, when an application window<br />
first appears on the screen, or when it is resized or exposed on the screen,<br />
AWT receives a native expose event and issues a Java event to have the window<br />
paint itself. Similarly, when the state of a component changes, such as when a<br />
button is pressed, Swing issues a paint request to make sure that the button is<br />
displayed in a pressed state. Applications can also issue a paint request to<br />
Swing directly; this type of request is done in situations in which the application<br />
code may know, on the basis of changes in some internal state, that the display<br />
should change.<br />
>In general, painting happens automatically; Swing detects when a component’s<br />
contents have been altered such that the component needs to be repainted. Your<br />
application does not normally need to issue paint requests to Swing unless it<br />
knows that there has been some change to the display state that would not automatically<br />
trigger a repaint. For example, if you change the text in a JLabel component,<br />
Swing knows to repaint that label with the new text. But if your<br />
application has detected a change to some internal variable, such as a variable<br />
that affects the translucency of a component, then it might need to tell Swing that<br />
a paint should be performed.<br />
There are a handful of methods in components that are used to initiate painting.<br />
These methods fall into two main categories: asynchronous requests and synchronous<br />
requests.<br />
<br />
Asynchronous Repaint Requests<br />
-----------------------------<br />
These requests work by telling Swing what needs to be updated and letting<br />
Swing handle the details of scheduling those requests and combining the requests<br />
as appropriate.1 All of the asynchronous requests are variants of the repaint()<br />
method. There are several of these methods, but they basically come in two flavors:<br />
those that request the entire component be updated and those that specify<br />
an area that needs to be updated.<br />
<br />
1.Component.repaint() ---- repaints the entire component and its children<br />
2.Component.repaint(int x, int y, int width, int height) ---- repaints only the specified region<br />
<br />
#The simpler repaint() method is equivalent to calling repaint(0, 0, getWidth(), getHeight()).<br />
#Asynchronous repaint requests are coalesced; requests are combined to remove redundant requests<br />
<br />
Synchronous Paint Requests<br />
--------------------------<br />
>to invoke synchronous paint requests, you must be on EDT<br />
>paint requests are not queued, by served right away<br />
>paint requests are not coalesced as in the case of asynchronous requests<br />
<br />
1.call one of JComponent.paintImmediately(int x, int y, int w, int h) or<br />
JComponent.paintImmediately(Rectangle r) methods to paint synchronously<br />
<br />
paintImmediately() is the only method that you should need to<br />
call to force a synchronous paint of a component’s contents. This method tells<br />
the component that the specified area must be updated; Swing calls paint()<br />
internally on all of the appropriate components to make this happen.<br />
<br />
2.call Component.paint(Graphics) method<br />
<br />
Swing Rendering<br />
---------------<br />
>Swing painting: Repaint request is handled by the RepaintManager, which<br />
calls paint() on the component, which then renders its content, its border, and its children.<br />
>The Swing rendering model is straightforward and centers on Swing’s singlethreaded<br />
painting model. First, the paint request is placed onto the event queue,<br />
as described previously. Sometime later, on the EDT, the event is dispatched to<br />
the Swing RepaintManager object, which calls paint() on the appropriate<br />
component. That paint call results in a component painting first its own content,<br />
then its border, and finally any components that it contains (which are called its<br />
children).<br />
>In this way, an entire hierarchy of components, from the JFrame down to the<br />
lowliest button, gets rendered. Note that this is a back-to-front method of painting,<br />
where the backmost content (starting with the JFrame itself) gets rendered,then the items in that component, then the items in that component, and so on, until the frontmost components get displayed.<br />
<br />
From Back to Front Painting: In graphics, this method is known as the painter’s algorithm, where a scene, like that in an oil painting,<br />
is rendered from back to front, with the objects in front covering the objects in the background.<br />
Of course, this method doesn’t apply to all paintings. Watercolors, for example, do not work well<br />
with this algorithm because all of the colors blend together instead of covering (the Swing equivalent<br />
would be if all components were translucent). And many modern paintings, such as those by<br />
Jackson Pollock, appear to use algorithms that are more reminiscent of rendering artifacts.<br />
<br />
<br />
The trick is figuring out where your application needs to plug into this system in<br />
order to get the right stuff painted at the right time. There are three things that<br />
your application should be concerned about:<br />
<br />
• JComponent.paintComponent(Graphics): Applications that have components<br />
with any custom rendering, such as Filthy Rich Clients, may need<br />
to override this method to perform that custom rendering. This rendering<br />
might include drawing graphics inside a canvas, but it also includes doing<br />
anything custom to a standard component, such as rendering a gradient for<br />
the background of a button. Standard Swing components already handle<br />
this functionality for their graphics, so it is only for the case of custom components<br />
with specialized rendering that this method must be overridden.<br />
• Component.paint(Graphics): For the most part, Swing applications do<br />
not override paint() directly, unlike older AWT applications. However,<br />
there are important situations for Filthy Rich Clients when overriding<br />
paint() is crucial because by doing so we can set up the graphics state that<br />
will be used by a component and its children.<br />
• JComponent.setOpaque(boolean): Applications may need to call<br />
setOpaque(false) on a component depending on whether the component’s<br />
rectangular bounds are not completely opaque. This action ensures<br />
that Swing does the right thing for nonopaque components by rendering<br />
contents behind the component appropriately. Note that all Swing components<br />
except for JLabel are opaque by default.<br />
<br />
public class OvalComponent extends JComponent {<br />
public void paintComponent(Graphics g) {<br />
g.setColor(getBackground());<br />
g.fillRect(0, 0, getWidth(), getHeight());<br />
g.setColor(Color.GRAY);<br />
g.fillOval(0, 0, getWidth(), getHeight());<br />
}<br />
}<br />
<br />
paint()<br />
-------<br />
Overriding paint() is not necessary in many Swing applications. In fact, overriding<br />
paint() is not really recommended practice in general for Swing applications.<br />
This recommendation is in contrast to older AWT applications, where<br />
overriding paint() was equivalent to overriding paintComponent() in Swing;<br />
this is how applications got custom rendering behavior in some components of<br />
their applications. In Swing, however, the paint() method in JComponent,<br />
which is the superclass for all Swing components, handles everything that any<br />
rendering Swing component would typically want. JComponent’s paint()<br />
method handles painting the content, borders, and children of any Swing component.<br />
Swing’s painting model also handles double-buffering, which we read<br />
more about shortly. It is the ability of JComponent to handle all of this functionality for paint() that<br />
makes overriding paint() not recommended in general; subclasses may neglect<br />
to do something (like drawing borders or painting children) that they should do.<br />
It is far better to just let JComponent handle these details instead. But sometimes<br />
overriding paint() is useful and necessary.<br />
<br />
Tip: There is one important case in which it is useful for custom Swing components<br />
to override paint(): when an application wants to alter the graphics state for all of<br />
that component’s rendering.<br />
A good example of this situation is a translucent component, where the user will<br />
see through the component to items that lie behind it in the GUI. If you want a<br />
Swing component, including its children and borders, to be completely translucent,<br />
then you must change the Composite attribute of the Graphics object passed<br />
into the paint() method. You could, of course, change the Graphics object<br />
passed into paintComponent(), but that would alter the rendering only for that<br />
component’s contents. JComponent creates a new Graphics object for each call to<br />
paintComponent(), so altering the state of that Graphics object will affect only<br />
the contents of that single component. What you should do instead is alter the<br />
Graphics object that the contents, the borders, and the children are rendered with.<br />
In this case, you should alter the Graphics object passed to the paint() method.<br />
<br />
>JButton.setHorizontalAlignment()/JButton.setVerticalAlignment() position both icon and text inside the button<br />
>JButton.setHorizontalTextPosition()/JButton.setVerticalTextPosition() position the text relative to the icon<br />
<br />
<br />
-----------------------------<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>JAVA SWING 2 OREILLY<br />
-----------------------------<br />
>If the possible values of a formatted text field have an obvious order, use a spinner instead. A spinner uses a formatted text field by default, but adds two buttons that enable the user to choose a value in a sequence.<br />
<br />
>Another alternative or adjunct to using a formatted text field is installing an input verifier on the field. A component's input verifier is called when the component nearly loses the keyboard focus. The input verifier enables you to check whether the value of the component is valid and optionally change it or stop the focus from being transferred.<br />
<br />
>Creating your own component, or extending an existing one, requires a deeper understanding of Swing. This includes a firm understanding of Swing architecture, events, and lower-level classes. Also, if you decide to subclass a Swing component, the responsibilities of that component must be adopted and handled accordingly—otherwise, your new component may perform erratically.<br />
<br />
Finally, you may wish to change the L&F of one or more Swing components. This is arguably the most complex of the three routes that you can take—it requires a thorough knowledge of the design, architectural fundamentals, and graphical primitives of each lightweight component. In addition, you need to understand how Swing's UIManager and UIDefaults classes work together to "set" each component's L&F.<br />
<br />
>plaf=pluggable look and feel<br />
<br />
>Swing actually uses a simplified variant of the MVC design called the model-delegate. This design combines the view and the controller object into a single element, the UI delegate, which draws the component to the screen and handles GUI events. Bundling graphics capabilities and event handling is somewhat easy in Java, since much of the event handling is taken care of in AWT. As you might expect, the communication between the model and the UI delegate then becomes a two-way street<br />
<br />
The Z-Order Caveat: Lightweight and Heavyweight Components<br />
-----------------------------------------------------------<br />
> Because of z-order, it is not advisable to mix lightweight and heavyweight components in Swing.<br />
>heavyweight components(JApplet, JFrame, JDialog, and JWindow) are always "opaque"—they have a rectangular shape and are nontransparent. This is because the host operating system typically allocates the entire painting region to the component, clearing it first.<br />
>The remaining components are lightweight. So here is the crux of the dilemma: when a lightweight component is placed inside a heavyweight container, it shares (and actually borrows) the graphics context of the heavyweight component. The lightweight component must always draw itself on the same plane as the heavyweight component that contains it; as a result, it shares the z-order of the heavyweight component. In addition, lightweight components are bound to the clipping region of the top-level window or dialog that contains them. In effect, lightweight components are all "drawings" on the canvas of a heavyweight component. The drawings cannot go beyond the boundaries of the canvas and can always be covered by another canvas. Heavyweight components, however, are free from this restriction. Therefore, they always appear on top of the lightweight components — whether that is the intent or not.<br />
>Heavyweight components have other ramifications in Swing as well. They do not work well in scrollpanes, where they can extend beyond the clipping boundaries; they also don't work in front of lightweight menus and menu bars (unless certain precautions are taken) or inside internal frames. Some Swing classes, however, offer an interesting approach to this problem. These classes allow you to specify whether the component draws itself using a lightweight or a heavyweight window. Hence, with a bit of judicious programming, you can keep your components correctly rendered—no matter where they are located.<br />
<br />
Understanding Actions<br />
---------------------<br />
Actions are a popular addition to Swing. An action allows a programmer to bundle a commonly used procedure and its bound properties (such as its name and an image to represent it) into a single class. This construct comes in handy if an application needs to call upon a particular function from multiple sources. For example, let's say that a Swing programmer creates an action that saves data to disk. The application could then invoke this action from both the Save menu item on the File menu and the Save button on a toolbar. Both components reference the same action object, which saves the data. If the Save function is disabled for some reason, this property can be set in the action as well. The menu and toolbar objects are automatically notified that they can no longer save any data, and they can relay that information to the user.<br />
<br />
3.1.1 Actions and Containers<br />
----------------------------<br />
Swing containers, such as JMenu, JPopupMenu, and JToolBar, can each accept action objects with their add( ) methods. When an action is added, these containers automatically create a GUI component, which the add( ) method then returns to you for customization. For example, a JMenu or a JPopupMenu creates and returns a JMenuItem from an Action while a JToolBar creates and returns a JButton. The action is then paired with the newly created GUI component in two ways: the GUI component registers as a PropertyChangeListener for any property changes that might occur in the action object, while the action object registers as an ActionListener on the GUI component. Figure 3-1 shows the interactions between a menu item or toolbar and an Action.<br />
<br />
Essentially, this means that if the menu item or button is selected by the user, the functionality inside the action is invoked. On the other hand, if the action is disabled, it sends a PropertyChangeEvent to both the menu item and the toolbar, causing them to disable and turn gray. Similarly, if the action's icon or name is changed, the menu and toolbar are automatically updated.<br />
<br />
>i.e, changes in Action object properties cause update to GUI components and user actions in GUI components invoke Action object<br />
<br />
3.1.2 The Action Interface<br />
--------------------------<br />
An action is defined by the interface it implements, in this case javax.swing.Action. Action extends the ActionListener interface from AWT; this forces concrete classes that implement Action to provide an actionPerformed( ) method. The programmer uses the actionPerformed( ) method to implement whatever behavior is desired. For example, if you are creating a Save action, you should put the code that saves the data inside of your actionPerformed( ) method.<br />
<br />
When the action is added to an accepting container such as JMenu, JPopupMenu, or JToolBar, the container automatically registers the action as an ActionListener of the GUI component it creates. Consequently, if the GUI component is selected by the user, it simply invokes the actionPerformed( ) method of the action to do its job.<br />
<br />
The Action interface defines five constants (shown in Table 3-2), which serve as keys for storing standardized Action properties. The method of storage varies from implementer to implementer, but a Hashtable is common. These properties store information such as the name of the action, its description, and a representative icon. Also, the Action interface defines a boolean property that indicates whether the action is enabled or disabled. Recall that the GUI component created for the action registers itself as a PropertyChangeListener. Hence, if any of these properties are modified, the GUI component is notified and can react accordingly.<br />
<br />
Table 3-1. String-based key constants for the Action interface <br />
Constant - Meaning<br />
<br />
DEFAULT<br />
Default setting<br />
<br />
NAME<br />
Name of the action<br />
<br />
SHORT_DESCRIPTION<br />
Short text description of what the action does<br />
<br />
LONG_DESCRIPTION<br />
Long text description of what the action does<br />
<br />
SMALL_ICON<br />
Represents a small icon; typically used in a toolbar<br />
<br />
<br />
<br />
3.1.2.1 Property<br />
----------------<br />
The Action interface defines the property shown in Table 3-2.<br />
<br />
Table 3-2. Action property Property<br />
enabled - boolean<br />
·<br />
<br />
The enabled property defines whether anyone can invoke the action. When this property changes, the action should fire a PropertyChangeEvent describing the change.<br />
<br />
Note that the properties whose keys appear in Table 3-1 are not also shown here. These are really properties because changing one should fire a PropertyChangeEvent. However, because they do not use standard accessors, they do not fit the true JavaBeans property model, so we have omitted them from Table 3-2.<br />
<br />
3.1.2.2 Methods<br />
public abstract Object getValue(String key)<br />
public abstract void putValue(String key, Object value)<br />
Store various keyed properties for the action. A string-based key is used to index the values. Several string constants representing the keys are shown in Table 3-1. When putValue( ) is called with any property, and the value passed in is different than what was there previously, the implementing object must fire a PropertyChangeEvent describing the change to all registered listeners.<br />
<br />
public abstract void actionPerformed(ActionEvent e)<br />
This method is required by the ActionListener interface (it does not actually exist in the Action interface). Any concrete class that implements the Action interface must provide an actionPerformed( ) method that performs whatever task the action is supposed to accomplish.<br />
<br />
3.1.2.3 Events<br />
---------------<br />
Objects implementing the Action interface must fire a PropertyChangeEvent when any keyed property is changed, or when the action is enabled or disabled. Containers that accept actions typically listen for these PropertyChangeEvent notifications so they can update their own properties or appearances.<br />
<br />
public abstract void addPropertyChangeListener(PropertyChangeListener listener)<br />
public abstract void removePropertyChangeListener(PropertyChangeListener listener)<br />
Add or remove the specified PropertyChangeListener from the event listener list.<br />
<br />
3.1.3 The AbstractAction Class<br />
------------------------------<br />
The AbstractAction class is an abstract implementation of the Action interface. AbstractAction provides the default functionality for almost all methods in the Action interface. You can extend this class to create your own specific actions. If you do so, the only method for which you must provide an implementation is the actionPerformed( ) method, which provides the functionality for the action. Here is a simple example:<br />
<br />
class MyAction extends AbstractAction {<br />
<br />
public MyAction(String text, Icon icon) {<br />
super(text,icon);<br />
}<br />
public void actionPerformed(ActionEvent e) {<br />
System.out.println("Action [" + e.getActionCommand( ) + "]!");<br />
}<br />
}<br />
Here, we simply print the action command sent with the ActionEvent. You can add more features based on the contents of the ActionEvent.<br />
<br />
<br />
3.3.1 Headless Modes<br />
--------------------<br />
One other variation on the graphics environment is "headless" operation. This mode of running without any monitor shows up quite often on back-end systems. Java servlets trying to use the AWT, 2D, and Swing classes to draw dynamic graphs for a web page are a classic example of applications that need a graphics environment on a machine that might not have any graphics displays. You can detect such a case with the GraphicsEnvironment.isHeadless( ) call.<br />
<br />
If an environment is headless, there are certain calls that cannot be made. These calls tend to create onscreen components such as frames or dialogs—no good without a head—or otherwise attempt to interact with the (nonexistent) local user. Table 3-4 shows the documented Swing components that generate a HeadlessException when called. Since HeadlessException is an unchecked exception (i.e., a descendant of RuntimeException), it is not always documented in the Javadoc for a method or in its throws clause (in the source code). The best practice that has evolved for writing Javadoc for such exceptions requires that the Javadoc mention the exception (with an @throws entry), but that the throws clause in the actual method signature omit it. This leads to a visual indication that it is an unchecked exception. Not all code has adopted this best practice, of course.<br />
<br />
Table 3-4. Swing components that throw HeadlessException Component<br />
Method(s)<br />
<br />
JApplet<br />
Constructors<br />
<br />
JColorChooser<br />
showDialog( ); setDragEnabled( ); createDialog( ); constructors<br />
<br />
JDialog<br />
Constructors<br />
<br />
JFileChooser<br />
createDialog( ); showDialog( ); showOpenDialog( ); showSaveDialog( ); setDragenabled( )<br />
<br />
JFrame<br />
Constructors<br />
<br />
JList<br />
setDragEnabled( )<br />
<br />
JOptionPane<br />
All show dialog methods; createDialog( ); getFrameForComponent( ); getWindowForComponent( ); getRootFrame( )<br />
<br />
JTable<br />
setDragEnabled( )<br />
<br />
JTree<br />
setDragEnabled( )<br />
<br />
JWindow<br />
Constructors<br />
<br />
SwingUtilities<br />
getSharedOwnerFrame( )<br />
<br />
3.4 Sending Change Events in Swing<br />
-----------------------------------<br />
Swing uses two different change event classes. The first is the standard java.beans.PropertyChangeEvent class. This class passes a reference to the object, sending the change notification as well as the property name, its old value, and its new value. The second, javax. swing.event.ChangeEvent, is a lighter version that passes only a reference to the sending object—in other words, the name of the property that changed, as well as the old and new values, are omitted.<br />
<br />
Since the ChangeEvent class is not part of the JavaBeans specifications, properties that use this event are not "bound" according to the JavaBeans standard. In order to prevent confusion, properties that use a ChangeEvent to notify listeners of property changes have not been marked as bound in our property tables.<br />
<br />
Because the ChangeEvent includes only a reference to the event originator, which never changes, you can always define a single ChangeEvent and reuse it over and over when firing events from your component.<br />
<br />
3.4.1 The ChangeEvent Class<br />
---------------------------<br />
The ChangeEvent is a stripped-down version of the java.beans.PropertyChangeEvent class. This class has no methods or properties, only a constructor. This simplicity makes it a popular class for developers wanting to fire off their own events. Recipients get a reference to the source of the event but then must query the source directly to find out what just happened. It's great for quick notifications or instances in which the state of the source component is so complex it's hard to predict which pieces of information the recipient will need, but it shouldn't be used simply to save the component author a little time at the expense of runtime inefficiency if the recipient always needs to look up information that could have been part of a PropertyChangeEvent.<br />
<br />
3.4.1.1 Constructor<br />
public ChangeEvent(Object source)<br />
The constructor for the ChangeEvent class. It takes only a single object, which represents the entity sending the event.<br />
<br />
3.4.2 The ChangeListener Interface<br />
Objects that intend to receive change events must implement the com.sun.java.swing.event.ChangeListener interface. They can then register to receive ChangeEvent objects from a publisher class. The ChangeListener interface consists of only one method.<br />
<br />
3.4.2.1 Method<br />
public abstract void stateChanged(ChangeEvent e)<br />
Implemented in a listener object to receive ChangeEvent notifications.<br />
<br />
--<br />
The ColorModel abstract class encapsulates the methods for translating a pixel value to color components (for example, red, green, and blue) and an alpha component. In order to render an image to the screen, a printer, or another image, pixel values must be converted to color and alpha components. As arguments to or return values from methods of this class, pixels are represented as 32-bit ints or as arrays of primitive types. The number, order, and interpretation of color components for a ColorModel is specified by its ColorSpace. A ColorModel used with pixel data that does not include alpha information treats all pixels as opaque, which is an alpha value of 1.0.<br />
--<br />
An Insets object is a representation of the borders of a container. It specifies the space that a container must leave at each of its edges. The space can be a border, a blank space, or a title.<br />
--<br />
<br />
3.5 The JComponent Class<br />
-------------------------<br />
JComponent is an abstract class that almost all Swing components extend; it provides much of the underlying functionality common throughout the Swing component library. Just as the java.awt.Component class serves as the guiding framework for most of the AWT components, the javax.swing.JComponent class serves an identical role for the Swing components. We should note that the JComponent class extends java.awt.Container (which in turn extends java.awt.Component), so it is accurate to say that Swing components carry with them a great deal of AWT functionality as well.<br />
<br />
Because JComponent extends Container, many Swing components can serve as containers for other AWT and Swing components. These components may be added using the traditional add( ) method of Container. In addition, they can be positioned with any Java layout manager while inside the container. The terminology remains the same as well: components that are added to a container are said to be its children; the container is the parent of those components. Following the analogy, any component that is higher in the tree is said to be its ancestor , while any component that is lower is said to be its descendant.<br />
<br />
Recall that Swing components are considered "lightweight." In other words, they do not rely on corresponding peer objects within the operating system to render themselves. As we mentioned in Chapter 1, lightweight components draw themselves using the standard features of the abstract Graphics object, which not only decreases the amount of memory each component uses but allows components to have transparent portions and take on nonrectangular shapes. And, of course, lightweight components are free of a dedicated L&F.<br />
<br />
It's not out of the question to say that a potential benefit of using lightweight components is a decrease in testing time. This is because the functionality necessary to implement lightweight components in the Java virtual machine is significantly less than that of heavyweight components. Heavyweight components must be individually mapped to their own native peers. On the other hand, one needs to implement only a single lightweight peer on each operating system for all the Swing components to work correctly. Hence, there is a far greater chance that lightweight components will execute as expected on any operating system and not require rounds of testing for each platform.<br />
<br />
Because all Swing components extend Container, you should be careful that you don't add( ) to Swing components that aren't truly containers. The results range from amusing to destructive.<br />
<br />
<br />
<br />
<br />
In JDK 1.2, JComponent reuses some of the functionality of the java.awt.Graphics2D class. This consists primarily of responsibilities for component painting and debugging.<br />
<br />
3.5.1 Inherited Properties<br />
Swing components carry with them several properties that can be accessed through JComponent but otherwise originate with AWT. Before we go any further, we should review those properties of java.awt.Container and java.awt.Component that can be used to configure all Swing components. This discussion is relatively brief; if you need a more thorough explanation of these AWT classes, see Java AWT Reference by John Zukowski (O'Reilly), which can be downloaded from this book's web site, http://www.oreilly.com/catalog/jswing2/. Table 3-5 lists the properties that JComponent inherits from its AWT superclasses.<br />
<br />
Table 3-5. Properties inherited from the AWT Component and Container classes Property<br />
Data type<br />
get<br />
is<br />
set<br />
Default value (if applicable)<br />
<br />
background<br />
Color<br />
·<br />
·<br />
<br />
<br />
colorModel<br />
ColorModel<br />
·<br />
<br />
<br />
componenti<br />
Component<br />
·<br />
<br />
<br />
componentCount<br />
int<br />
·<br />
<br />
<br />
components<br />
Component[]<br />
·<br />
<br />
<br />
cursor<br />
Cursor<br />
·<br />
·<br />
Cursor.DEFAULT_CURSOR<br />
<br />
enabled<br />
boolean<br />
·<br />
·<br />
true<br />
<br />
font<br />
Font<br />
·<br />
·<br />
<br />
foreground<br />
Color<br />
·<br />
·<br />
<br />
insets<br />
Insets<br />
·<br />
Insets(0,0,0,0)<br />
<br />
layout<br />
LayoutManager<br />
·<br />
·<br />
BorderLayout( )<br />
<br />
locale<br />
Locale<br />
·<br />
·<br />
<br />
location<br />
Point<br />
·<br />
·<br />
<br />
locationOnScreen<br />
Point<br />
·<br />
·<br />
<br />
name<br />
String<br />
·<br />
·<br />
""<br />
<br />
parent<br />
Container<br />
·<br />
·<br />
null<br />
<br />
size<br />
Dimension<br />
·<br />
·<br />
<br />
showing<br />
boolean<br />
·<br />
true<br />
<br />
valid<br />
boolean<br />
·<br />
<br />
visible<br />
boolean<br />
·<br />
·<br />
true<br />
<br />
iindexed<br />
<br />
<br />
<br />
Let's discuss these properties briefly. The background and foreground properties indicate which colors the component uses to paint itself. We should mention that with Swing the background property is disabled if the component is transparent (not opaque). The read-only colorModel property returns the current model used to translate colors to pixel values; generally, the user does not need to access this property. The font property lets you get or set the font used for displaying text in the component.<br />
<br />
The indexed component property maintains a list of all the components inside the container. You can tell how many there are with the integer componentCount property. If you want to access all of them through a Component array, retrieve the components property. The insets property specifies the current insets of the container, while the layout property indicates which layout manager is managing the components of the container. Technically, this means that you can use any component as a container. Don't be misled; if a component doesn't seem like a reasonable container, it probably can't be used as one. (Don't, for example, try to add a JButton to a JScrollBar.) A number of components use these properties for internal, specialized layout managers and components.<br />
<br />
The locale property specifies the internationalization locale for the application. The location property indicates the x,y coordinates of the component's upper-left corner in the container's coordinate space. If you want to see the location of the component's upper-left corner in screen coordinates, use the read-only locationOnScreen property.<br />
<br />
The name property gives this component a string-based name that components can display if they choose. The parent property references the container that is acting as this component's parent, or null if there is none. The size property specifies the component's current height and width in pixels.<br />
<br />
The showing property indicates whether the component is currently showing on the screen, while the visible property tells if the component is marked to be drawn on the screen. There's an odd, nonintuitive relationship between visible and showing. A component that is visible isn't necessarily showing. "Visible" means that a component is capable of being displayed; "showing" means that the component is actually displayed (though it may be obscured by something else). Most containers (JPanel, JFrame, etc.) are invisible by default; most other components (JButton, etc.) are visible by default. So if you add a JButton to an invisible JFrame, for example, the button is visible but not showing. It can be displayed but happens to be in a container that isn't currently displayed.<br />
<br />
Finally, if the valid property is false, the component needs to be resized or moved by the component's layout manager. If it is true, the component is ready to be displayed.<br />
<br />
>Container.invalidate() - mark as invalid(requiring component layout again)<br />
>Container.validate() - layout the components properly<br />
>JComponent.revalidate() = invalidate() + validate() --> it marks the root container in the component hierarchy as invalid by calling invalidate() and adds it to the list of components that must be validated; it the validation is later done in EDT thread after all currenty pending events are dispatched.<br />
<br />
3.5.2 Common Methods<br />
--------------------<br />
Here are some other frequently called methods for working with Swing components:<br />
<br />
public Component add(Component comp)<br />
public Component add(Component comp, int index)<br />
public void add(Component comp, Object constraints)<br />
public void add(Component comp, Object constraints, int index)<br />
Add a component to the container, given the optional constraints and the current index.<br />
<br />
public void remove(int index)<br />
public void remove(Component comp)<br />
public void removeAll( )<br />
Remove the appropriate component from the container. The final method empties the entire container.<br />
<br />
public void pack( )<br />
This method of java.awt.Window resizes the window to encompass the preferred size of all the contained components, as placed by the current layout manager. It's a good idea to call pack( ) after you've added components to a top-level container with a layout manager, such as JFrame, JApplet, JDialog, and JWindow.<br />
<br />
public void validate( )<br />
public void invalidate( )<br />
The invalidate( ) method is typically called on a Container to indicate that its children need to be laid out, or on a Component to indicate that it needs to be re-rendered. This method is often called automatically. However, certain changes to a Component (such as changing the size of a button by changing its label or font) do not cause it to be invalidated. In such cases, invalidate( ) must be called on the Component to mark it as invalid, and validate( ) must be called on its Container. The validate( ) method is typically called to validate, lay out, and repaint a Container. Calling this method is especially important when you add or remove Components in a Container that is already displayed.<br />
<br />
Swing improves the validate( )/invalidate( ) situation a bit by calling invalidate( ) in response to many property changes, saving you from having to make the call. Unfortunately, there are still situations (such as changing a JButton's font) that do not trigger an automatic invalidate( ) call, so you'll still have to explicitly call invalidate( ) in these cases.<br />
<br />
The key things to take away from these methods are:<br />
<br />
You may need to call invalidate( ) if you make changes to the appearance of a displayed component.<br />
<br />
You must call validate( ) on Containers that have been invalidated (typically by the addition or invalidation of a child).<br />
<br />
As a result of deprecation and the movement toward JavaBeans accessors, AWT has some methods with multiple names. For example, show( ) and setVisible(true) are essentially the same. It is always better to use the JavaBeans-style name—setVisible( ) in this case—when working with Swing; the newer name is less confusing for people familiar with the JavaBeans conventions.<br />
<br />
3.5.4 UI Delegates and UIClassIDs<br />
---------------------------------<br />
As we mentioned in Chapter 1, all Swing components use a modified MVC architecture. Each Swing component is responsible for maintaining two unique objects: a model and a UI delegate. The object representing the model handles the state information specific to the component while the UI delegate determines how the component paints itself based on the model's state information.<br />
<br />
Note that there is no property for a model in JComponent. You typically access the model property at the level of a JComponent subclass. This is because each Swing component defines its own data model, which is unique from that of all other components. The UI delegate property, on the other hand, can be handled at the JComponent level because the methods for rendering lightweight components are always the same. These methods (e.g., installUI( ), uninstallUI( ), setUI( ), paint( )) can be traced back to the abstract class javax.swing.plaf.ComponentUI, which serves as the superclass for all UI delegates.<br />
<br />
JComponent contains a reference to the current UI delegate for the object. JComponent allows a subclass to alter the component's UI delegate with the protected setUI( ) method; this method effectively resets the L&F of the component. The UI therefore acts like a write-only property, but we hesitate to call it a property because its mutator isn't public. Invoking setUI( ) by itself, however, does not change the display. A call to updateUI( ) is also required, which forces the component to redraw itself. If you are looking to change the entire L&F of the application, it is better to change it universally with the setLookAndFeel( ) method of UIManager than to change it one component at a time. See Chapter 2 for a simple example of how to work with various L&Fs.<br />
<br />
Each Swing component maintains a read-only string constant, UIClassID, that identifies the type of UI delegate that it uses. Most Swing components override the accessor getUIClassID( ) and return a string constant, typically the letters "UI" appended to the name of the component (without the "J"). This string is then used by Swing's UI manager to match the component with a UI delegate for the current L&F. For example, a JButton object has a UIClassID string of ButtonUI. If the current L&F is Metal, the UIManager can figure out that the MetalButtonUI is the correct UI-delegate class to use<br />
<br />
>UIDelegate does the paint()<br />
>RepaintManager does the repaint()<br />
>JComponent is responsible for paiting the component, its border and its children in that order(thru UIDelegate of course)<br />
<br />
Components drawn last are always on top; hence, child components always paint over their parents. JComponent contains three protected methods that it uses to complete this functionality:<br />
<br />
protected void paintComponent(Graphics g)<br />
<br />
protected void paintBorder(Graphics g)<br />
<br />
protected void paintChildren(Graphics g)<br />
<br />
<br />
>similar to above methods, print methods were introduced but they internally call the above methods only. This is to allow users to add any special treatments while printing the components<br />
<br />
printComponent(Graphics g) { paintComponent(g);}<br />
printBorder(Graphics g) { paintBorder(g);}<br />
printChildren(Graphics g) { paintChildren(g);}<br />
<br />
>transparent component's background is ignored<br />
<br />
>JComponent can optimize its repainting time if none of its children overlap; this is because the repaint manager does not have to compute the hidden and visible areas for each child component before rendering them. Some containers, such as JSplitPane, are designed so that overlap between child components is impossible, so this optimization works nicely. Other containers, such as JLayeredPane, have support for child components that can overlap. JComponent contains a property that Swing frequently calls upon to see if it can optimize component drawing: optimizedDrawingEnabled. In JComponent, this property is set to true by default. If overlap occurs in a subclass of JComponent, the subclass should override the isOptimizedDrawingEnabled( ) accessor and return false. This prevents the repaint manager from using the optimized drawing process when rendering the container's children.<br />
<br />
JComponent contains a boolean read-only property (paintingTile) that indicates whether the component is currently in the process of painting a tile , which is a child component that does not overlap any other children. The isPaintingTile( ) method returns true until all tiles have been painted.<br />
<br />
<br />
>The validateRoot property is false by default. If it is set to true, it designates this component as the root component in a validation tree. Recall that each time a component in a container is invalidated, its container is invalidated as well, along with all of its children. This causes an invalidation to move all the way up the component hierarchy, stopping only when it reaches a component for which isValidateRoot( ) returns true. Currently, the only components that set this property to true are JRootPane (which is used by all the Swing top-level components), JScrollPane, and JTextField.<br />
<br />
>The visibleRect property is a Rectangle that indicates the intersection of the component's visible rectangles with the visible rectangles of all of its ancestors. Why the intersection? Remember that you can have a contained object that is clipped by its parent. For example, you can move an internal frame so that a portion of it falls outside the parent window's clipping region. Therefore, the visible portion (the portion that is actually drawn to the screen) consists only of the intersection of the parent's visible portion and the child's visible portion. You typically do not need to access this property.<br />
<br />
>The topLevelAncestor property contains a reference to the top-level window that contains this component, usually a JWindow or JApplet.<br />
<br />
>location[x,y] - position of the upper left corner of the component relative to the parents coordinate space<br />
x - horizontal distance(of upper left corner of the child) from parent's upper left corner<br />
y - vertical downwards distance(of upper left corner of the child) from parent's upper left corner<br />
size = width and height of the child from point(x,y)<br />
bounds = Rectangle(x,y,width,height)<br />
<br />
>If a Rectangle is supplied, the getBounds( ) method alters each of the fields in the passed-in Rectangle to reflect the component's current size and position, returning a copy of it. If the reference passed in is a null, the method instantiates a new Rectangle object, sets its values, and returns it. You can use the former approach to reduce the number of garbage rectangles created and discarded over multiple calls to getBounds( ), which increases the efficiency of your application.<br />
<br />
>The setBounds( ) method alters the component's size and position. This method also takes a Rectangle object. If the new settings are different from the previous settings, the component is moved, typically resized, and invalidated. If the component has a parent, it is invalidated as well. Be warned that various layout managers may override any changes you attempt to make to the bounds property. Invalidating a component with a call to setBounds( ) may force the layout manager to recompute and reset the bounds of the component in relation to the other components, resolving it to the same size as before.<br />
<br />
>You can still use the setSize( ) and setLocation( ) methods of java.awt.Component if you prefer to code with those as well. Again, note that when altering the size of the component, the layout manager may override the new value and reset it to its previous value, thus ignoring your new size values.<br />
<br />
The three well-known AWT sizing properties, minimumSize, preferredSize, and maximumSize, are accessible through JComponent. minimumSize indicates the smallest size for the component when it is in a container. preferredSize contains the size at which the container's layout manager should strive to draw the component. maximumSize indicates the largest size the component should be when displayed in a container. If none of these properties are set by the user, they are always calculated by the component's UI delegate or directly by the layout manager of the container, in that order. The methods setMinimumSize( ), setPreferredSize, and setMaximumSize( ) allow you to change these properties without subclassing.<br />
<br />
>Finally, JComponent contains two read/write properties that help interested layout managers align the component in a container: alignmentX and alignmentY. Both of these properties contain floating-point values between 0.0 and 1.0; the numbers determine the position of the component relative to any siblings. A number closer to 0 indicates that the component should be positioned closer to the left or top side, respectively. A perfect 0.5 indicates that the component should be placed at the center, while a number nearing 1 indicates that the component should be positioned closer to the right or bottom. Currently, the only layout managers that use these properties are the BoxLayout and OverlayLayout managers; all AWT 1.1 layout managers ignore these properties and position their children by other means.<br />
<br />
>It's easy to add borders to Swing components, a feature AWT lacks.<br />
>One important characteristic of Swing is that if a border property is set on a component, the border overrides the component's insets property. Swing allows the programmer to specify an empty border, so you can still pad the component with extra space as well as provide a border if you use a CompoundBorder. If the border property is null, the default insets are used for the component instead.<br />
>CompoundBorder - stacking multiple borders on top of each other<br />
<br />
3.5.8 Working with Tooltips<br />
---------------------------<br />
JComponent also provides Swing components with support for tooltips. Tooltips are small windows of text that pop up when the user rests the mouse over the target component. They typically supplement the meaning of an icon or button, but they can also provide the user with instructions or important information about the underlying component. The tooltip usually disappears after a designated amount of time (four seconds by default) or if the mouse is moved outside of the component's bounds.<br />
<br />
JComponent does not manage tooltips by itself; it gets help from the ToolTipManager class. The ToolTipManager continually scans for mouse events on components that have tooltips. When the mouse passes into a component with a tooltip set, the ToolTipManager begins a timer. If the mouse has not left the component's region in 0.75 seconds, a tooltip is drawn at a preset location near the component. If the mouse has moved out of a region for longer than 0.5 seconds, the tooltip is removed from the screen.<br />
<br />
With the default setToolTipText( ) and getToolTipText( ) methods, JComponent handles the creation of an appropriate tooltip. If you want to get more creative, however, Swing provides a separate object for tooltips: JToolTip. With it, you can completely redefine the characteristics of a tooltip by declaring your own JToolTip object and overriding the createToolTip( ) method of JComponent to return it to the ToolTipManager on demand.<br />
<br />
3.5.9 Client Properties<br />
-----------------------<br />
Swing components can maintain a special table of properties called "client properties." This provides specialized properties that can be meaningful in components only in certain instances. For example, let's assume that a specific L&F uses a client property to store information about how a component should display itself when that L&F is activated. As you might guess, this client property would be meaningless when another L&F is activated. Using the client properties approach allows various L&Fs to expand their component properties without deluging the Swing source base with L&F-specific data.<br />
<br />
The name "client properties" is somewhat confusing because client properties are distinct from JavaBeans-style properties. Obviously, there's a big difference: unlike JavaBeans properties, you can create new client properties without subclassing; you can even create new client properties at runtime. These two methods in JComponent store and retrieve client properties:<br />
<br />
myComponent.putClientProperty("aClientProperty", Boolean.TRUE);<br />
Boolean result = (Boolean)getClientProperty("aClientProperty");<br />
Because we are using a hashtable, the properties must be objects and not primitive data types; we must use the Boolean object instead of simply setting true or false.<br />
<br />
3.5.10 Double Buffering<br />
-----------------------<br />
The JComponent class allows all Swing components to take advantage of double buffering. The idea behind double buffering is that it takes longer for a component to render its individual parts on screen than it does for a rectangular-area copy to take place. If the former occurs over multiple screen refreshes, the human eye is likely to catch the component in the process of being drawn, and it may appear to flicker. With the latter, the screen is usually updated as fast as the monitor can refresh itself.[2]<br />
<br />
[2] Area copies are always faster because they are performed by the operating system or even the graphics card of the computer. At this level, they are commonly referred to as "bit-block transfers," or BitBLTs.<br />
<br />
When double buffering is activated in Swing, all component rendering performed by the repaint manager is done in an offscreen buffer. Upon completion, the contents of the offscreen buffer are quickly copied (not redrawn) on the screen at the component's position. You can request double buffering for a particular component by accessing the boolean doubleBuffered property of JComponent. Passing in true to the setDoubleBuffered( ) method enables double buffering; false shuts it off:<br />
<br />
JButton button = new JButton("Test Button");<br />
button.setDoubleBuffered(true); // Turns on double buffering<br />
You can use the isDoubleBuffered( ) method to check if double buffering is currently enabled on a Swing component. The component level setting is only a request, and Swing double buffering may be completely disabled at the level of the repaint manager (for example, when running under an operating system like Mac OS X, double buffering is always performed by the window manager, so doing it again in Swing would simply throw away processor cycles for no benefit). See Section 28.4.2 for more details and for information about how you can use graphics-accelerated "volatile images" in SDK 1.4 to further speed up Swing double buffering.<br />
<br />
With double buffering, transparency is maintained in nonopaque components because the graphics underneath the component are copied into the buffer before any offscreen rendering takes place. However, there is a slight penalty for double buffering nonopaque components because Swing performs two area copies instead of one: one to copy the context in which the component is drawn to the offscreen buffer before drawing, and one to copy this context plus the rendered component back to the screen.<br />
<br />
Buffers also chew up a great deal of memory, so the repaint manager tries to avoid using more than one offscreen buffer at a time. For example, if an offscreen buffer has been set for both a container and one of its children, the buffer for the parent container is used for both components.<br />
<br />
3.5.12 The DebugGraphics Class<br />
------------------------------<br />
Lightweight components are rendered entirely in Java, as opposed to offloading their work to a native heavyweight peer. The abstract Graphics class outlines platform-independent implementations for line-drawing, image-painting, and area-copying and filling that a lightweight peer can call upon to draw itself. If you create your own component, or extend an existing one, a Graphics object is often passed to the UI delegate's paint( ) method to help with the drawing.<br />
<br />
Sometimes the way you intend a component to be painted, however, isn't how it appears on the screen. Debugging painting problems can prove to be troublesome, especially when dealing with transparency, opaqueness, and double buffering. JComponent, however, can generate a special version of the Graphics object, called DebugGraphics, which it can pass to a UI delegate's paint( ) method. This object can take a set of user-configurable debugging options that modify how a component is drawn to the screen.<br />
<br />
If you wish to activate debugging for the component's graphics, you can pass one or more debugging flags (see Table 3-7) into JComponent's setDebugGraphicsOptions( ) method.<br />
<br />
Table 3-7. Constants for DebugGraphics options DebugGraphics constant<br />
Description<br />
<br />
DebugGraphics.FLASH_OPTION<br />
Causes each graphics primitive to flash a configurable number of times as it is being rendered.<br />
<br />
DebugGraphics.LOG_OPTION<br />
Prints a text message to the screen as each graphics primitive is drawn.<br />
<br />
DebugGraphics.BUFFERED_OPTION<br />
Raises a window that shows the drawing that is taking place in the offscreen buffer. This is useful in the event that the double-buffered feature has been activated.<br />
<br />
DebugGraphics.NONE_OPTION<br />
Disables all debug graphics options.<br />
<br />
<br />
<br />
The debug options outlined in Table 3-7 are bits in a binary mask; you can set more than one at the same time by using the bitwise OR ( | ) operator, as shown here:<br />
<br />
JButton myButton = new JButton("Hello"); // JButton extends JComponent.<br />
myButton.setDebugGraphicsOptions(DebugGraphics.FLASH_OPTION<br />
| DebugGraphics.LOG_OPTION);<br />
When any of the debug graphics options are set, the getComponentGraphics( ) method of JComponent returns a DebugGraphics object instead of a normal Graphics object. As we mentioned earlier, the same type of object is passed to the UI delegate of the component. When a component draws itself, it calls upon the functionality of the DebugGraphics object to perform the task, just as it would with a typical Graphics object. The drawing primitives are then slowed or logged so that the user can help identify any problems.<br />
<br />
Focus Cycle<br />
-----------<br />
Focus - component having focus is responsible for consuming keyboard and mouse events<br />
Focus Cycle - set of components that can be traversed using Tab key in a cyclic manner<br />
<br />
>A group of components within a single container can define a focus cycle of its own. If the container has its own focus cycle, the focus repeatedly traverses through all of its children that accept the focus. The focus cycle is typically determined by the location of components in the container, although you can create your own focus traversal policy if you require different behavior. With the default focus policy, the component closest to the top-left corner of the container always receives focus first. The focus then moves from left to right across the components, and from top to bottom. Figure 3-9 shows how the default focus cycle shifts focus between components in a container.<br />
<br />
>If a container has a focus cycle of its own, it should override the Container method isFocusCycleRoot( ) and return true. If the method returns true, then the container is known as the root container of the focus cycle.<br />
<br />
With SDK 1.2 or 1.3, you can explicitly name the component that should receive the focus after a given JComponent by setting its nextFocusableComponent property. In addition, focus can be programmatically requested through the JComponent method requestFocus( ), which the focus manager can call to shift the focus to this component. This is often done when the user selects the object (i.e., presses a JButton). If you don't want your component to be able to respond to requestFocus( ) calls, you can set the requestFocusEnabled property of JComponent to false.<br />
<br />
With SDK 1.4, this method of managing focus was replaced by the more flexible FocusTraversalPolicy class as part of a major overhaul of the whole focus system. This class allows you to define a focus policy to manage a container. (In this case, "focus policy" simply means an algorithm to figure out which component follows, and which one precedes, the current component in the focus cycle.) One advantage of moving to policy-based management is that generic policies can be developed for containers—no more need to hook up individual components.<br />
<br />
There is an important distinction here: setting the requestFocusEnabled property to false does not mean that the focus cannot be traversed onto your component; it simply means that it cannot be programmatically requested. JComponent provides a similar property, focusable,[4] that you can enable or disable to specify whether a component ever receives focus at all.<br />
<br />
>3.5.14 Keyboard Events<br />
Swing components can be programmed to trigger various actions when certain keystrokes occur. For example, components automatically handle focus-related keyboard events. The default focus mechanism watches for Tab and Shift-Tab keystrokes, adjusting the focus and consuming the keystrokes. If the focus mechanism does not know how to handle a keystroke, and no registered low-level KeyListeners have consumed it, JComponent checks to see whether the processComponentKeyEvent( ) method consumes it. The default implementation does nothing, the idea being that you can override it in a subclass if you want to react to a keystroke in your own way. You're not likely to want to use that approach, though, because it's much less flexible than what happens next: if nothing has consumed the key event, JComponent checks to see if a keyboard action has been registered for that keystroke. A set of maps provide a convenient way to translate key events to appropriate component-related actions.<br />
<br />
Translation to an action starts by converting the key event to the KeyStroke that represents it. This is used as a key to check the component's InputMap for a corresponding action name (the InputMap could return any kind of object, but convention dictates that it be a String corresponding to a logical action name). The result of this lookup, if not null, is used in turn as a key to look in the component's ActionMap for an Action to perform. Assuming that a non-null Action was found, its actionPerformed method is invoked (as described in Section 3.1.2 earlier in this chapter).<br />
<br />
It might seem like overkill to use a two-map lookup like this. Wouldn't it be simpler to just put the Actions directly in the InputMap? It turns out there are a couple of good reasons for the second layer. Although a given type of component generally supports a well-defined set of logical operations, the specific Action classes that implement them often vary depending on the L&F in use. Similarly, the keys that are used to invoke the actions vary between L&Fs, which leads to a complex coupling between the component and the L&F-specific UI delegate. Separating the two concepts into two maps provides an easy-to-understand translation between KeyStrokes and logical event names, and from event names to specific Action implementations. It also means that InputMaps are nicely self-documenting; it's easy to turn them into a human-readable table that shows the functions assigned to various keys.[5]<br />
<br />
[5] For more details about the design goals of this key-binding mechanism, which was introduced in SDK 1.3, see http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html, which also describes the limitations of the previous mechanism. If you are still working with a pre-1.3 version of Swing, you can find the first edition's version of this section, which discusses how to use the old key-binding mechanism, on this book's web site, http://www.oreilly.com/catalog/jswing2/.<br />
<br />
InputMaps and ActionMaps are also designed to be easy to share between components (or even similar component types). They have a parent property that is checked if a binding isn't found, so common functionality can be placed in a shared parent map, and component-specific definitions added to a local map on an as-needed basis; the text components make extensive use of this capability. JComponent makes this easy by providing newly initialized components with empty InputMaps and ActionMaps whose parents are the (likely shared) map provided by the UI. So, as a developer, you never need to worry about the possible existence of shared maps; you can just start adding your custom mappings and rely on Swing to provide the rest.<br />
<br />
Before showing you the details of how to register keyboard actions, there is one more complication to clarify. The process outlined here described a single InputMap used to translate keystrokes to action names. In fact, components have three separate InputMaps to address the fact that there are different situations under which a component might be asked to respond to a keyboard event. The most obvious case, which probably sprang to mind, is when the component itself is the owner of the keyboard focus. Components can also have a chance to respond to key events if they don't have focus in two other cases. First, a component may respond if it is an ancestor of (contains) the focused component. Think of a ScrollPane, in which the Page Up and Page Down keys remain functional even though you're working with the contents of the pane rather than the pane itself. Second, a component may respond if it is simply inside a window that is focused (this is how button mnemonics work). In order to create the proper InputMap, the methods to manipulate them offer a condition parameter whose legal values are shown in Table 3-8.<br />
<br />
Table 3-8. Constants for InputMap selection Constant<br />
Description<br />
<br />
WHEN_FOCUSED<br />
The InputMap used when the component has the focus<br />
<br />
WHEN_IN_FOCUSED_WINDOW<br />
The InputMap used when the component resides in a container that has the focus<br />
<br />
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT<br />
The InputMap used when the component is the ancestor of (contains) the component that currently has the focus<br />
<br />
<br />
<br />
You obtain a component's input map through one of the following two methods (these were mentioned in Table 3-6, but bear repeating in this context):<br />
<br />
public InputMap getInputMap(int condition)<br />
Return the input map to be used under the specified condition.<br />
<br />
public InputMap getInputMap( )<br />
A convenience method that calls getInputMap(WHEN_FOCUSED), which is the most commonly used condition.<br />
<br />
Looking up the action map is simpler since there's only one method:<br />
<br />
public ActionMap getActionMap( )<br />
Return the action map associated with the component.<br />
<br />
A brief example illustrates how to perform the common task of assigning an event to a component using this binding mechanism. Suppose we wanted to extend the example program in Section 3.1.3.5 to perform a download whenever the F8 key is pressed. One way we could do this is by adding the following lines to the end of the ActionExample constructor:<br />
<br />
exampleButon.getActionMap( ).put("download", exampleAction);<br />
exampleButton.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(<br />
KeyStroke.getKeyStroke("F8"), "download");<br />
The first line binds the logical action name download to our sample download action within the button's action map. The second line causes the F8 key to trigger this logical action whenever the button's window has the focus, even if the button itself does not. This two-step registration process in which both an InputMap and the ActionMap are retrieved and modified is very common when working with custom actions because of the two-stage, key-mapping process. If you're simply changing or adding bindings for a standard keystroke or action, you need to work with only one of the maps.<br />
<br />
To remove a binding you've set, both types of maps provide a remove method that takes a KeyStroke object that will be removed from the mapping. The clear method removes all mappings. Neither of these methods affect inherited mappings. In fact, if you added a keystroke that overrode an inherited mapping, removing that keystroke restores the inherited mapping. If you actually want to block an inherited mapping without providing a new action, register a mapping to the action "none", which convention mandates never has an Action bound to it.<br />
<br />
There are corresponding methods for setting the map properties themselves, of course. These are used far less commonly, but do provide a way to eliminate the inherited parent maps provided by the L&F's UI delegate:<br />
<br />
public void setInputMap(int condition)<br />
public void setActionMap(ActionMap actionMap)<br />
Replace the corresponding map completely, eliminating any inherited mappings. Passing a null argument causes the component to have no bindings at all.<br />
<br />
Note that if you replace the mappings this way, there's no way to get back the previously inherited mappings unless you keep a reference to the original maps yourself.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
--------------------------------------------------------------------------------|<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>SWING <span class="Apple-tab-span" style="white-space: pre;"> </span>|<br />
--------------------------------------------------------------------------------|<br />
<br />
>Swing is part of the Java Foundation Classes (JFC). The JFC also include other features important to a GUI program, such as the ability to add rich graphics functionality and the ability to create a program that can work in different languages and by users with different input devices.<br />
<br />
>Pluggable Look-and-Feel Support<br />
Any program that uses Swing components has a choice of look and feel. The JFC classes shipped by Sun and Apple provide a look and feel that matches that of the platform. The Synth package allows you to create your own look and feel. The GTK+ look and feel makes hundreds of existing look and feels available to Swing programs.<br />
<br />
A program can specify the look and feel of the platform it is running on, or it can specify to always use the Java look and feel, and without recompiling, it will just work. Or, you can ignore the issue and let the UI manager sort it out.<br />
<br />
>Accessibility API<br />
People with disabilities use special software — assistive technologies — that mediates the user experience for them. Such software needs to obtain a wealth of information about the running application in order to represent it in alternate media: for a screen reader to read the screen with synthetic speech or render it via a Braille display, for a screen magnifier to track the caret and keyboard focus, for on-screen keyboards to present dynamic keyboards of the menu choices and toolbar items and dialog controls, and for voice control systems to know what the user can control with his or her voice. The accessibility API enables these assistive technologies to get the information they need, and to programmatically manipulate the elements that make up the graphical user interface.<br />
<br />
>JFC = Swing + Pluggable LAF + Accessibility API + 2D API + Internationalization (AWT not part of JFC?)<br />
<br />
>Swing provides three general top level containers: JFrame, JDialog and JApplet<br />
<br />
>Each GUI component can be contained only once. If a component is already in a container and you try to add it to another container, the component will be removed from the first container and then added to the second.<br />
<br />
>Each top-level container has a content pane that, generally speaking, contains (directly or indirectly) the visible components in that top-level container's GUI.<br />
<br />
>You can optionally add a menu bar to a top-level container. The menu bar is by convention positioned within the top-level container, but outside the content pane. Some look and feels, such as the Mac OS look and feel, give you the option of placing the menu bar in another place more appropriate for the look and feel, such as at the top of the screen.<br />
<br />
>Note: Although JInternalFrame mimics JFrame, internal frames aren't actually top-level containers.<br />
<br />
>Content Pane and Menu Bar are parallel(peers) to each other<br />
<br />
Containment Hierarchy<br />
---------------------<br />
>Top level container is the root of the containment hierarchy<br />
>Every top level container has its own containment hierarchy<br />
----x---<br />
<br />
>JFrame.getContentPane() returns javax.swing.JPanel<br />
>But the return type of getContentPane() method is 'Container'<br />
>the default content pane uses BorderLayout as its layout manager<br />
>the default layout for JPanel is FlowLayout<br />
>you can set your own content pane using setContentPane() in the top level container<br />
<br />
>Note: As a convenience, the add method and its variants, remove and setLayout have been overridden to forward to the contentPane as necessary. This means you can write<br />
frame.add(child);<br />
and the child will be added to the contentPane.<br />
<br />
Note that only these three methods do this. This means that getLayout() will not return the layout set with setLayout().<br />
<br />
>Adding menu bar: JFrame.setJMenuBar()<br />
<br />
RootPane:<br />
---------<br />
>a reclusive pane used by top-level containers<br />
>RootPane manages content pane, menu bar and couple of other containers(LayeredPane and GlassPane)<br />
>you need to know RootPane to intercept mouse clicks or to paint over multiple components<br />
<br />
Panes from Bottom to Top<br />
------------------------<br />
<br />
Frame -> RootPane -> LayeredPane -> ContentPane + MenuBar -> GlassPane<br />
<br />
>LayeredPane contains ContentPane and MenuBar<br />
>LayeredPane enables z-ordering of other components<br />
>GlassPane is used to intercept input events occuring over top-level containers<br />
>GlassPane is also used to paint over multiple components<br />
<br />
JComponent<br />
----------<br />
>Except for top-level containers all other components whose name start with J are descendants of JComponent<br />
>JFrame, JDialog and JApplet derive from AWT containers not from JComponent<br />
>JPanel, JScrollPane, JButton, JTable, etc derive from JComponent<br />
>AWT component hierarchy from parent to child<br />
<br />
java.lang.Object <- java.awt.Component <- java.awt.Container <- java.awt.Window <- java.awt.Frame/java.awt.Dialog<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> java.awt.Container <- java.awt.Panel <- java.applet.Applet<br />
<br />
>JFrame, JDialog and JApplet derive from their equivalent awt components (Frame, Dialog and Applet respectively)<br />
>JComponent extends java.awt.Container<br />
>java.awt.Component is the root of all UI related components<br />
>java.awt.Component includes everything from providing layout hints to supporting painting *and* events<br />
>java.awt.Container has support for adding components and laying out them<br />
>JComponent Features:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>1.Tooltips<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>2.Painting and borders<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>3.Application-wide pluggable look and feel<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>4.Custom properties<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>5.Support for layout<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>6.Support for accessibility<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>7.Support for drag and drop<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>8.Double buffering<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>9.Key bindings<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>setToolTipText() - set tool tip<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>setBorder() - sets the border outside<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>paintComponent() - painting insides of the component<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Application-wide pluggable look and feel -<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Behind the scenes, each JComponent object has a corresponding ComponentUI object that performs all the drawing, event handling, size determination, and so on for that JComponent. Exactly which ComponentUI object is used depends on the current look and feel, which you can set using the UIManager.setLookAndFeel method.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>putClientProperty()/getClientProperty() - set custom properties to component as name/object pairs(e.g. constraints objects)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>getPreferredSize()/getAlignmentX()/setMinimumSize()/setMaximumSize()/setAlignmentX()/setAlignmentY() - layout support methods<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>double buffering - smooths on screen painting<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
------x-----<br />
<br />
>Get the preferred, maximum, or minimum size of the component, measured in pixels. Many JComponent classes have setter and getter methods. For those non-JComponent subclasses, which do not have the corresponding setter methods, you can set a component's preferred, maximum, or minimum size by creating a subclass and overriding these methods.<br />
<br />
>Insets getInsets()<span class="Apple-tab-span" style="white-space: pre;"> </span> Get the size of the component's border.<br />
<br />
>void setBounds(int, int, int, int)<br />
void setBounds(Rectangle)<span class="Apple-tab-span" style="white-space: pre;"> </span> Set the size and location relative to the parent's upper left corner, in pixels, of the component. The four int arguments specify x, y, width, and height, in that order. Use these methods to position and size a component when you are not using a layout manager.<br />
<br />
Text Components<br />
----------------<br />
>Swing provides six text components, along with supporting classes and interfaces that meet even the most complex text requirements. In spite of their different uses and capabilities, all Swing text components inherit from the same superclass, JTextComponent, which provides a highly-configurable and powerful foundation for text manipulation.<br />
<br />
>JTextField - one line unstyled text<br />
JFormattedTextField - preformatted(e.g. date format) one line plain text<br />
JPasswordField - password masking<br />
JTextArea - multiline plain text; any font can be used; but all texts will be in a single font style only at a time<br />
JEditorPane - styled multi line multi font, html markup supported pane; can include icons<br />
JTextPane - styled text pane same as JEditorPane but also includes embedded components like Button<br />
<br />
>Each editing command is represented and implemented by an Action object. Actions allow you to associate a command with a GUI component, such as a menu item or button, and therefore build a GUI around a text component.<br />
<br />
>Note: By default, each undoable edit undoes a single character entry. It is possible with some effort to group edits so that a series of key strokes is combined into one undoable edit. Grouping edits in this manner would require you to define a class that intercepts undoable edit events from the document, combining them if appropriate and forwarding the results to your undoable edit listener.<br />
<br />
>A text component's model is known as a document and is an instance of a class that implements the Document interface. A document provides the following services for a text component:<br />
<br />
Contains the text. A document stores the textual content in Element objects, which can represent any logical text structure, such as paragraphs, or text runs that share styles. We do not describe Element objects here. However, The Swing Connection has at least one article on the subject.<br />
Provides support for editing the text through the remove and insertString methods.<br />
Notifies document listeners and undoable edit listeners of changes to the text.<br />
Manages Position objects, which track a particular location within the text even as the text is modified.<br />
Allows you to obtain information about the text, such as its length, and segments of the text as a string.<br />
<br />
>AbstractDocument implements Document<br />
PlainDocument extends AbstractDocument<br />
DefaultStyledDocument extends AbstractDocument implements StyledDocument<br />
HTMLDocument extends DefaultStyledDocument<br />
<br />
>TextFields, PasswordFields and TextAreas use PlainDocument as a default document<br />
>Oddly EditorPane(styled component) also uses PlainDocument by default<br />
>TextPane uses DefaultStyledDocument by default<br />
>To customize documents used by text components, use custom document or DocumentFilter<br />
<br />
Document Filter<br />
---------------<br />
>filters are used to police the modifications to the document<br />
>filters are called before the modification is committed to the documents<br />
>document listeners are called after the modifications are committed to the documents<br />
>You may want to change the document's text within a document listener. However, you should never modify the contents of a text component from within a document listener. If you do, the program will likely deadlock. Instead, you can use a formatted text field or provide a document filter.<br />
>use caret listener to get updated about caret position and text selection<br />
>use navigation filter to customize caret appearance and text selection<br />
>use DefaultEditorKit to perform editing actions/caret movement actions within text document<br />
>use StyledEditorKit to perform markup/html related editing actions on texts<br />
<br />
Editor Kits<br />
-----------<br />
>Text components use an EditorKit to tie the various pieces of the text component together. The editor kit provides the view factory, document, caret, and actions. An editor kit also reads and writes documents of a particular format. Although all text components use editor kits, some components hide theirs. You cannot set or get the editor kit used by a text field or text area. Editor panes and text panes provide the getEditorKit method to get the current editor kit and the setEditorKit method to change it.<br />
<br />
------x-------<br />
<br />
>Insets - specifies the size of the border<br />
<br />
>At most one button in a top-level container can be the default button. The default button typically has a highlighted appearance and acts clicked whenever the top-level container has the keyboard focus and the user presses the Return or Enter key.<br />
<br />
>if an applet uses Swing components it has to inherit from JApplet<br />
>the only heavy weight swing containers: JFrame, JDialog, JWindow and JApplet<br />
>light weight swing container: JInternalFrame<br />
>interface RootPaneContainer is to mark the container as a user of single RootPane. all swing top-level containers implement RootPaneContainer interface; provides methods to get/set GlassPane, ContentPane and LayeredPane; and to get RootPane<br />
>The diagram at right shows the structure of a JRootPane. A JRootpane is made up of a glassPane, an optional menuBar, and a contentPane. (The JLayeredPane manages the menuBar and the contentPane.) The glassPane sits over the top of everything, where it is in a position to intercept mouse movements. Since the glassPane (like the contentPane) can be an arbitrary component, it is also possible to set up the glassPane for drawing. Lines and images on the glassPane can then range over the frames underneath without being limited by their boundaries.<br />
>Although the menuBar component is optional, the layeredPane, contentPane, and glassPane always exist. Attempting to set them to null generates an exception.<br />
>To add components to the JRootPane (other than the optional menu bar), you add the object to the contentPane of the JRootPane, like this:<br />
<br />
rootPane.getContentPane().add(child);<br />
<br />
The same principle holds true for setting layout managers, removing components, listing children, etc. All these methods are invoked on the contentPane instead of on the JRootPane.<br />
<br />
>Note: The default layout manager for the contentPane is a BorderLayout manager. However, the JRootPane uses a custom LayoutManager. So, when you want to change the layout manager for the components you added to a JRootPane, be sure to use code like this:<br />
rootPane.getContentPane().setLayout(new BoxLayout());<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
>If a JMenuBar component is set on the JRootPane, it is positioned along the upper edge of the frame. The contentPane is adjusted in location and size to fill the remaining area. (The JMenuBar and the contentPane are added to the layeredPane component at the JLayeredPane.FRAME_CONTENT_LAYER layer.)<br />
<br />
>The layeredPane is the parent of all children in the JRootPane -- both as the direct parent of the menu and the grandparent of all components added to the contentPane. It is an instance of JLayeredPane, which provides the ability to add components at several layers. This capability is very useful when working with menu popups, dialog boxes, and dragging -- situations in which you need to place a component on top of all other components in the pane.<br />
<br />
>The glassPane sits on top of all other components in the JRootPane. That provides a convenient place to draw above all other components, and makes it possible to intercept mouse events, which is useful both for dragging and for drawing. Developers can use setVisible on the glassPane to control when the glassPane displays over the other children. By default the glassPane is not visible.<br />
<br />
>The custom LayoutManager used by JRootPane ensures that:<br />
<br />
The glassPane fills the entire viewable area of the JRootPane (bounds - insets).<br />
The layeredPane fills the entire viewable area of the JRootPane. (bounds - insets)<br />
The menuBar is positioned at the upper edge of the layeredPane.<br />
The contentPane fills the entire viewable area, minus the menuBar, if present.<br />
Any other views in the JRootPane view hierarchy are ignored.<br />
<br />
>If you replace the LayoutManager of the JRootPane, you are responsible for managing all of these views. So ordinarily you will want to be sure that you change the layout manager for the contentPane rather than for the JRootPane itself!<br />
<br />
>A check box generates one item event and one action event per click. Usually, you listen only for item events, since they let you determine whether the click selected or deselected the check box.<br />
<br />
>You can use ButtonGroup with any set of objects that inherit from AbstractButton. Typically a button group contains instances of JRadioButton, JRadioButtonMenuItem, or JToggleButton. It would not make sense to put an instance of JButton or JMenuItem in a button group because JButton and JMenuItem do not implement the select/deselect button state.<br />
<br />
Removing or Replacing the Preview Panel<br />
---------------------------------------<br />
JColorChooser:<br />
<br />
By default, the color chooser displays a preview panel. ColorChooserDemo2 removes the text color chooser's preview panel with this line of code:<br />
tcc.setPreviewPanel(new JPanel());<br />
This effectively removes the preview panel because a plain JPanel has no size and no default view. To set the preview panel back to the default, use null as the argument to setPreviewPanel.<br />
<br />
Creating a Custom Chooser Panel<br />
-------------------------------<br />
The default color chooser provides five chooser panels:<br />
Swatches — for choosing a color from a collection of swatches.<br />
HSV — for choosing a color using the Hue-Saturation-Value color representation. Prior to JDK 7, this was called HSB, for Hue-Saturation-Brightness.<br />
HSL — for choosing a color using the Hue-Saturation-Lightness color representation. This is new in JDK 7.<br />
RGB — for choosing a color using the Red-Green-Blue color model.<br />
CMYK — for choosing a color using the process color or four color model. This is new in JDK 7.<br />
You can extend the default color chooser by adding chooser panels of your own design with addChooserPanel, or you can limit it by removing chooser panels with removeChooserPanel.<br />
If you want to remove all of the default chooser panels and add one or more of your own, you can do this with a single call to setChooserPanels. ColorChooserDemo2 uses this method to replace the default chooser panels with an instance of CrayonPanel, a custom chooser panel. Here is the call to setChooserPanels from that example:<br />
<br />
//Override the chooser panels with our own.<br />
AbstractColorChooserPanel panels[] = { new CrayonPanel() };<br />
tcc.setChooserPanels(panels);<br />
The code is straighforward: it creates an array containing the CrayonPanel. Next the code calls setChooserPanels to set the contents of the array as the color chooser's chooser panels.<br />
CrayonPanel is a subclass of AbstractColorChooserPanel and overrides the five abstract methods defined in its superclass:<br />
<br />
void buildChooser()<br />
Creates the GUI that comprises the chooser panel. The example creates four toggle buttons — one for each crayon — and adds them to the chooser panel.<br />
void updateChooser()<br />
This method is called whenever the chooser panel is displayed. The implementation of this method selects the toggle button that represents the currently selected color.<br />
public void updateChooser() {<br />
Color color = getColorFromModel();<br />
if (Color.red.equals(color)) {<br />
redCrayon.setSelected(true);<br />
} else if (Color.yellow.equals(color)) {<br />
yellowCrayon.setSelected(true);<br />
} else if (Color.green.equals(color)) {<br />
greenCrayon.setSelected(true);<br />
} else if (Color.blue.equals(color)) {<br />
blueCrayon.setSelected(true);<br />
}<br />
}<br />
String getDisplayName()<br />
Returns the display name of the chooser panel. The name is used on the tab for the chooser panel. Here is the example getDisplayName method:<br />
public String getDisplayName() {<br />
return "Crayons";<br />
}<br />
<br />
Icon getSmallDisplayIcon()<br />
Returns a small icon to represent this chooser panel. This is currently unused. Future versions of the color chooser might use this icon or the large one to represent this chooser panel in the display. The example implementation of this method returns null.<br />
Icon getLargeDisplayIcon()<br />
Returns a large icon to represent this chooser panel. This is currently unused. Future versions of the color chooser might use this icon or the small one to represent this chooser panel in the display. The example implementation of this method returns null.<br />
<br />
ComboBox<br />
--------<br />
Combo boxes require little screen space, and their editable (text field) form is useful for letting the user quickly choose a value without limiting the user to the displayed values. Other components that can display one-of-many choices are groups of radio buttons and lists. Groups of radio buttons are generally the easiest for users to understand, but combo boxes can be more appropriate when space is limited or more than a few choices are available. Lists are not terribly attractive, but they're more appropriate than combo boxes when the number of items is large (say, over 20) or when selecting multiple items might be valid.<br />
<br />
Note: Be careful when implementing a custom model for a combo box. The JComboBox methods that change the items in the combo box's menu, such as insertItemAt, work only if the data model implements the MutableComboBoxModel interface (a subinterface of ComboBoxModel). Refer to the API tables to see which methods are affected.<br />
Something else to watch out for — even for uneditable combo boxes — is ensuring that your custom model fires list data events when the combo box's data or state changes. Even immutable combo box models, whose data never changes, must fire a list data event (a CONTENTS_CHANGED event) when the selection changes. One way to get the list data event firing code for free is to make your combo box model a subclass of AbstractListModel.<br />
<br />
Combo boxes also generate item events, which are fired when any of the items' selection state changes. Only one item at a time can be selected in a combo box, so when the user makes a new selection the previously selected item becomes unselected. Thus two item events are fired each time the user selects a different item from the menu. If the user chooses the same item, no item events are fired. Use addItemListener to register an item listener on a combo box.<br />
<br />
Although JComboBox inherits methods to register listeners for low-level events — focus, key, and mouse events, for example — we recommend that you don't listen for low-level events on a combo box. Here's why: A combo box is a compound component — it is comprised of two or more other components. The combo box itself fires high-level events such as action events. Its subcomponents fire low-level events such as mouse, key, and focus events. The low-level events and the subcomponent that fires them are look-and-feel-dependent. To avoid writing look-and-feel-dependent code, you should listen only for high-level events on a compound component such as a combo box.<br />
<br />
A renderer for a combo box must implement the ListCellRenderer interface. A combo box's editor must implement ComboBoxEditor.<br />
<br />
Note that combo boxes and lists use the same type of renderer — ListCellRenderer. You can save yourself some time by sharing renderers between combo boxes and lists, if it makes sense for your program.<br />
<br />
Dialogs<br />
-------<br />
Every dialog is dependent on a Frame component. When that Frame is destroyed, so are its dependent Dialogs. When the frame is iconified, its dependent Dialogs also disappear from the screen. When the frame is deiconified, its dependent Dialogs return to the screen. A swing JDialog class inherits this behavior from the AWT Dialog class.<br />
<br />
A Dialog can be modal. When a modal Dialog is visible, it blocks user input to all other windows in the program. JOptionPane creates JDialogs that are modal. To create a non-modal Dialog, you must use the JDialog class directly.<br />
<br />
The JDialog class is a subclass of the AWT java.awt.Dialog class. It adds a root pane container and support for a default close operation to the Dialog object . These are the same features that JFrame has, and using JDialog directly is very similar to using JFrame. If you're going to use JDialog directly, then you should understand the material in Using Top-Level Containers and How to Make Frames, especially Responding to Window-Closing Events.<br />
<br />
Even when you use JOptionPane to implement a dialog, you're still using a JDialog behind the scenes. The reason is that JOptionPane is simply a container that can automatically create a JDialog and add itself to the JDialog's content pane.<br />
<br />
The two most useful showXxxDialog methods are showMessageDialog and showOptionDialog. The showMessageDialog method displays a simple, one-button dialog. The showOptionDialog method displays a customized dialog — it can display a variety of buttons with customized button text, and can contain a standard text message or a collection of components.<br />
<br />
The other two showXxxDialog methods are used less often. The showConfirmDialog method asks the user to confirm something, but presents standard button text (Yes/No or the localized equivalent, for example) rather than button text customized to the user situation (Start/Cancel, for example). A fourth method, showInputDialog, is designed to display a modal dialog that gets a string from the user, using either a text field, an uneditable combo box or a list.<br />
<br />
JOptionPane (constructor)<br />
-------------------------<br />
Creates a JOptionPane with the specified buttons, icons, message, title, and so on. You must then add the option pane to a JDialog, register a property-change listener on the option pane, and show the dialog.<br />
<br />
Component parentComponent<br />
-------------------------<br />
The first argument to each showXxxDialog method is always the parent component, which must be a Frame, a component inside a Frame, or null. If you specify a Frame or Dialog, then the Dialog will appear over the center of the Frame and follow the focus behavior of that Frame. If you specify a component inside a Frame, then the Dialog will appear over the center of that component and will follow the focus behavior of that component's Frame. If you specify null, then the look and feel will pick an appropriate position for the dialog — generally the center of the screen — and the Dialog will not necessarily follow the focus behavior of any visible Frame or Dialog.<br />
The JOptionPane constructors do not include this argument. Instead, you specify the parent frame when you create the JDialog that contains the JOptionPane, and you use the JDialog setLocationRelativeTo method to set the dialog position.<br />
<br />
Object initialValue<br />
Specifies the default value to be selected.<br />
<br />
--<br />
As the previous code snippets showed, the showMessageDialog, showConfirmDialog, and showOptionDialog methods return an integer indicating the user's choice. The values for this integer are YES_OPTION, NO_OPTION, CANCEL_OPTION, OK_OPTION, and CLOSED_OPTION. Except for CLOSED_OPTION, each option corresponds to the button the user pressed. When CLOSED_OPTION is returned, it indicates that the user closed the dialog window explicitly, rather than by choosing a button inside the option pane.<br />
<br />
Even if you change the strings that the standard dialog buttons display, the return value is still one of the pre-defined integers. For example, a YES_NO_OPTION dialog always returns one of the following values: YES_OPTION, NO_OPTION, or CLOSED_OPTION.<br />
--<br />
<br />
If you do not care to limit the user's choices, you can either use a form of the showInputDialog method that takes fewer arguments or specify null for the array of objects. In the Java look and feel, substituting null for possibilities results in a dialog that has a text field and looks like this:<br />
<br />
Because the user can type anything into the text field, you might want to check the returned value and ask the user to try again if it is invalid. Another approach is to create a custom dialog that validates the user-entered data before it returns.<br />
<br />
--<br />
<br />
If you're designing a custom dialog, you need to design your dialog's API so that you can query the dialog about what the user chose. For example, CustomDialog has a getValidatedText method that returns the text the user entered.<br />
<br />
--<br />
<br />
Stopping Automatic Dialog Closing<br />
<br />
By default, when the user clicks a JOptionPane-created button, the dialog closes. But what if you want to check the user's answer before closing the dialog? In this case, you must implement your own property change listener so that when the user clicks a button, the dialog does not automatically close.<br />
DialogDemo contains two dialogs that implement a property change listener. One of these dialogs is a custom modal dialog, implemented in CustomDialog, that uses JOptionPane both to get the standard icon and to get layout assistance. The other dialog, whose code is below, uses a standard Yes/No JOptionPane. Though this dialog is rather useless as written, its code is simple enough that you can use it as a template for more complex dialogs.<br />
<br />
Besides setting the property change listener, the following code also calls the JDialog's setDefaultCloseOperation method and implements a window listener that handles the window close attempt properly. If you do not care to be notified when the user closes the window explicitly, then ignore the bold code.<br />
<br />
final JOptionPane optionPane = new JOptionPane(<br />
"The only way to close this dialog is by\n"<br />
+ "pressing one of the following buttons.\n"<br />
+ "Do you understand?",<br />
JOptionPane.QUESTION_MESSAGE,<br />
JOptionPane.YES_NO_OPTION);<br />
<br />
final JDialog dialog = new JDialog(frame,<br />
"Click a button",<br />
true);<br />
dialog.setContentPane(optionPane);<br />
dialog.setDefaultCloseOperation(<br />
JDialog.DO_NOTHING_ON_CLOSE);<br />
dialog.addWindowListener(new WindowAdapter() {<br />
public void windowClosing(WindowEvent we) {<br />
setLabel("Thwarted user attempt to close window.");<br />
}<br />
});<br />
optionPane.addPropertyChangeListener(<br />
new PropertyChangeListener() {<br />
public void propertyChange(PropertyChangeEvent e) {<br />
String prop = e.getPropertyName();<br />
<br />
if (dialog.isVisible()<br />
&& (e.getSource() == optionPane)<br />
&& (prop.equals(JOptionPane.VALUE_PROPERTY))) {<br />
//If you were going to check something<br />
//before closing the window, you'd do<br />
//it here.<br />
dialog.setVisible(false);<br />
}<br />
}<br />
});<br />
dialog.pack();<br />
dialog.setVisible(true);<br />
<br />
int value = ((Integer)optionPane.getValue()).intValue();<br />
if (value == JOptionPane.YES_OPTION) {<br />
setLabel("Good.");<br />
} else if (value == JOptionPane.NO_OPTION) {<br />
setLabel("Try using the window decorations "<br />
+ "to close the non-auto-closing dialog. "<br />
+ "You can't!");<br />
}<br />
--<br />
>Editor panes, by default, know how to read, write, and edit plain, HTML, and RTF text. Text panes inherit this capability but impose certain limitations. A text pane insists that its document implement the StyledDocument interface. HTMLDocument and RTFDocument are both StyledDocuments so HTML and RTF work as expected within a text pane. If you load a text pane with plain text though, the text pane's document is not a PlainDocument as you might expect, but a DefaultStyledDocument.<br />
<br />
>TextPanes only support StyledEditorKit only<br />
>Be aware that the read and write methods for StyleEditorKit work with plain text.<br />
>Through the API provided in the JTextPane class, you can embed images and components in a text pane. You can embed images in an editor pane, too, but only by including the images in an HTML or RTF file.<br />
<br />
----x----<br />
<br />
Swing Models<br />
<br />
>Although Swing's model architecture is sometimes referred to as a Model-View-Controller (MVC) design, it really isn't. Swing components are generally implemented so that the view and controller are indivisible, implemented by a single UI object provided by the look and feel. The Swing model architecture is more accurately described as a separable model architecture.<br />
<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-89179247985976305052012-06-07T07:53:00.000+05:302012-06-07T07:53:00.244+05:30GIST NOTES 20 - SQL<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 20 - SQL</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books/sources on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
RDBMS - Relational DB Management System<br />
SQL - Structured Query Language<br />
<br />
#SQL is not case sensitive<br />
#SQL DML and DDL<br />
<br />
SQL can be divided into two parts: The Data Manipulation Language (DML) and the Data Definition Language (DDL).<br />
<br />
The query and update commands form the DML part of SQL:<br />
<br />
SELECT - extracts data from a database<br />
UPDATE - updates data in a database<br />
DELETE - deletes data from a database<br />
INSERT INTO - inserts new data into a database<br />
The DDL part of SQL permits database tables to be created or deleted. It also defines indexes (keys), specifies links between tables, and imposes constraints between tables. The most important DDL statements in SQL are:<br />
<br />
CREATE DATABASE - creates a new database<br />
ALTER DATABASE - modifies a database<br />
CREATE TABLE - creates a new table<br />
ALTER TABLE - modifies a table<br />
DROP TABLE - deletes a table<br />
CREATE INDEX - creates an index (search key)<br />
DROP INDEX - deletes an index<br />
<br />
#KEYS:<br />
<br />
The relationships between columns located in different tables are usually described through the use of keys.<br />
<br />
As you can see we have a PRIMARY KEY in each table. The Primary key serves as a mechanism to refer to other fields within the same row. In this case, the Primary key is used to identify a relationship between a row under consideration and the person whose name is located inside the 'names' table. We use the AUTO_INCREMENT statement only for the 'names' table as we need to use the generated contact_id number in all the other tables for identification of the rows.<br />
<br />
This type of table design where one table establishes a relationship with several other tables is known as a 'one to many' relationship.<br />
In a 'many to many' relationship we could have several Auto Incremented Primary Keys in various tables with several inter-relationships.<br />
<br />
Foreign Key:<br />
<br />
A foreign key is a field in a table which is also the Primary Key in another table. This is known commonly as 'referential integrity'.<br />
<br />
<br />
#FULL TEXT INDEXING and Searching<br />
<br />
Since version 3.23.23, Full Text Indexing and Searching has been introduced into MySQL. FULLTEXT indexes can be created from VARCHAR and TEXT columns. FULLTEXT searches are performed with the MATCH function. The MATCH function matches a natural language query on a text collection and from each row in a table it returns relevance.The resultant rows are organized in order of relevance.<br />
<br />
Full Text searches are a very powerful way to search through text. But is not ideal for small tables of text and may produce inconsistent results. Ideally it works with large collections of textual data.<br />
<br />
Optimizing your Database<br />
<br />
Well, databases do tend to get large at some or the other. And here arises the issue of database optimization. Queries are going to take longer and longer as the database grows and certain things can be done to speed things up.<br />
<br />
Clustering<br />
<br />
The easiest method is that of 'clustering'. Suppose you do a certain kind of query often, it would be faster if the database contents were arranged in a in the same way data was requested. To keep the tables in a sorted order you need a clustering index. Some databases keep stuff sorted automatically.<br />
<br />
Ordered Indices<br />
<br />
These are a kind of 'lookup' tables of sorts. For each column that may be of interest to you, you can create an ordered index.<br />
It needs to be noted that again these kinds of optimization techniques produce a system load in terms of creating a new index each time the data is re-arranged.<br />
<br />
There are additional method such as B-Trees, Hashing which you may like to read up about but will not be discussed here.<br />
<br />
<br />
Replication<br />
<br />
Replication is the term given to the process where databases synchronize with each other. In this process one database updates it's own data with respect to another or with reference to certain criteria for updates specified by the programmer. Replication can be used under various circumstances. Examples may be : safety and backup, to provide a closer location to the database for certain users.<br />
<br />
<br />
What are Transactions ?<br />
<br />
In an RDBMS, when several people access the same data or if a server dies in the middle of an update, there has to be a mechanism to protect the integrity of the data. Such a mechanism is called a Transaction. A transaction groups a set of database actions into a single instantaneous event. This event can either succeed or fail. i.e .either get the job done or fail.<br />
<br />
The definition of a transaction can be provided by an Acronym called 'ACID'.<br />
<br />
(A)tomicity: If an action consists of multiple steps - it's still considered as one operation.<br />
<br />
(C) Consistency: The database exists in a valid and accurate operating state before and after a transaction.<br />
<br />
(I) Isolation: Processes within one transaction are independent and cannot interfere with that in others.<br />
<br />
(D) Durability: Changes affected by a transaction are permanent.<br />
<br />
To enable transactions a mechanism called 'Logging' needs to be introduced. Logging involves a DBMS writing details on the tables, columns and results of a particular transaction, both before and after, onto a log file. This log file is used in the process of recovery. Now to protect a certain database resource (ex. a table) from being used and written onto simulatneously several techniques are used. One of them is 'Locking' another is to put a 'time stamp' onto an action. In the case of Locking, to complete an action, the DBMS would need to acquire locks on all resources needed to complete the action. The locks are released only when the transaction is completed.<br />
<br />
Now if there were say a large numbers of tables involved in a particular action, say 50, all 50 tables would be locked till a transaction is completed.<br />
<br />
To improve things a bit, there is another technique used called 2 Phase Locking or 2PL. In this method of locking, locks are acquired only when needed but are released only when the transaction is completed.<br />
<br />
This is done to make sure that that altered data can be safely restored if the transaction fails for any reason.<br />
<br />
This technique can also result in problems such as "deadlocks".<br />
<br />
In this case - 2 processes requiring the same resources lock each other up by preventing the other to complete an action. Options here are to abort one, or let the programmer handle it.<br />
<br />
MySQL implements transactions by implementing the Berkeley DB libraries into its own code. So it's the source version you'd want here for MySQL installation. Read the MySQL manual on implementing this.<br />
<br />
<br />
Beyond MySQL<br />
<br />
<br />
What are Views ?<br />
<br />
A view allows you to assign the result of a query to a new private table. This table is given the name used in your VIEW query.<br />
Although MySQL does not support views yet a sample SQL VIEW construct statement would look like:<br />
<br />
CREATE VIEW TESTVIEW AS SELECT * FROM names;<br />
<br />
<br />
What are Triggers ?<br />
<br />
A trigger is a pre-programmed notification that performs a set of actions that may be commonly required. Triggers can be programmed to execute certain actions before or after an event occurs. Triggers are very useful as they they increase efficiency and accuracy in performing operations on databases and also are increase productivity by reducing the time for application development. Triggers however do carry a price in terms of processing overhead.<br />
<br />
<br />
What are Procedures ?<br />
<br />
Like triggers, Procedures or 'Stored' Procedures are productivity enhancers. Suppose you needed to perform an action using a programming interface to the database in say PERL and ASP. If a programmed action could be stored at the database level, it's obvious that it has to be written only once and cam be called by any programming language interacting with the database.<br />
<br />
Procedures are executed using triggers.<br />
<br />
<br />
Beyond RDBMS<br />
<br />
Distributed Databases (DDB)<br />
<br />
A distributed database is a collection of several, logically interrelated database located at multiple locations of a computer network. A distributed database management system permits the management of such a database and makes the operation transparent to the user. Good examples of distributed databases would be those utilized by banks, multinational firms with several office locations where each distributed data system works only with the data that is relevant to it's operations. DDBs have have full functionality of any DBMS. It's also important to know that the distributed databases are considered to be actually one database rather than discrete files and data within distributed databases are logically interrelated.<br />
<br />
Object Database Management Systems or ODBMS<br />
<br />
When the capabilities of a database are integrated with object programming language capababilities, the resulting product is an ODBMS. Database objects appear as programming objects in an ODBMS. Using an ODBMS offers several advantages. The ones that can be most readily appreciated are:<br />
<br />
1. Efficiency<br />
When you use an ODBMS, you're using data the way you store it. You will use less code as you're not dependent on an intermediary like SQL or ODBC. When this happens you can create highly complex data structures through your programming language.<br />
<br />
2. Speed<br />
When data is stored the way you'd like it to be stored (i.e. natively) there is a massive performance increase as no to-and-fro translation is required.<br />
<br />
<br />
#The SQL SELECT DISTINCT Statement<br />
<br />
In a table, some of the columns may contain duplicate values. This is not a problem, however, sometimes you will want to list only the different (distinct) values in a table.<br />
<br />
The DISTINCT keyword can be used to return only distinct (different) values.<br />
<br />
SQL SELECT DISTINCT Syntax<br />
<br />
SELECT DISTINCT column_name(s)<br />
FROM table_name<br />
<br />
##The WHERE Clause<br />
<br />
The WHERE clause is used to extract only those records that fulfill a specified criterion.<br />
<br />
SQL WHERE Syntax<br />
<br />
SELECT column_name(s)<br />
FROM table_name<br />
WHERE column_name operator value<br />
<br />
SELECT * FROM Persons<br />
WHERE City='Sandnes'<br />
<br />
##Quotes Around Text Fields<br />
<br />
SQL uses single quotes around text values (most database systems will also accept double quotes).<br />
<br />
Although, numeric values should not be enclosed in quotes.<br />
<br />
For text values:<br />
<br />
This is correct:<br />
<br />
SELECT * FROM Persons WHERE FirstName='Tove'<br />
<br />
This is wrong:<br />
<br />
SELECT * FROM Persons WHERE FirstName=Tove<br />
For numeric values:<br />
<br />
This is correct:<br />
<br />
SELECT * FROM Persons WHERE Year=1965<br />
<br />
This is wrong:<br />
<br />
SELECT * FROM Persons WHERE Year='1965'<br />
<br />
Operators Allowed in the WHERE Clause<br />
<br />
With the WHERE clause, the following operators can be used:<br />
<br />
Operator<span class="Apple-tab-span" style="white-space: pre;"> </span>Description<br />
=<span class="Apple-tab-span" style="white-space: pre;"> </span>Equal<br />
<><span class="Apple-tab-span" style="white-space: pre;"> </span>Not equal<br />
><span class="Apple-tab-span" style="white-space: pre;"> </span>Greater than<br />
<<span class="Apple-tab-span" style="white-space: pre;"> </span>Less than<br />
>=<span class="Apple-tab-span" style="white-space: pre;"> </span>Greater than or equal<br />
<=<span class="Apple-tab-span" style="white-space: pre;"> </span>Less than or equal<br />
BETWEEN<span class="Apple-tab-span" style="white-space: pre;"> </span>Between an inclusive range<br />
LIKE<span class="Apple-tab-span" style="white-space: pre;"> </span>Search for a pattern<br />
IN<span class="Apple-tab-span" style="white-space: pre;"> </span>If you know the exact value you want to return for at least one of the columns<br />
<br />
##AND and OR operators<br />
<br />
SELECT * FROM Persons<br />
WHERE FirstName='Tove'<br />
AND LastName='Svendson'<br />
<br />
SELECT * FROM Persons<br />
WHERE FirstName='Tove'<br />
OR FirstName='Ola'<br />
<br />
SELECT * FROM Persons WHERE<br />
LastName='Svendson'<br />
AND (FirstName='Tove' OR FirstName='Ola')<br />
<br />
##The ORDER BY Keyword<br />
<br />
The ORDER BY keyword is used to sort the result-set by a specified column.<br />
<br />
The ORDER BY keyword sort the records in ascending order by default.<br />
<br />
If you want to sort the records in a descending order, you can use the DESC keyword.<br />
<br />
SQL ORDER BY Syntax<br />
<br />
SELECT column_name(s)<br />
FROM table_name<br />
ORDER BY column_name(s) ASC|DESC<br />
<br />
SELECT * FROM Persons<br />
ORDER BY LastName DESC<br />
<br />
##The INSERT INTO Statement<br />
<br />
The INSERT INTO statement is used to insert a new row in a table.<br />
<br />
SQL INSERT INTO Syntax<br />
<br />
It is possible to write the INSERT INTO statement in two forms.<br />
<br />
The first form doesn't specify the column names where the data will be inserted, only their values:<br />
<br />
INSERT INTO table_name<br />
VALUES (value1, value2, value3,...)<br />
The second form specifies both the column names and the values to be inserted:<br />
<br />
INSERT INTO table_name (column1, column2, column3,...)<br />
VALUES (value1, value2, value3,...)<br />
<br />
INSERT INTO Persons<br />
VALUES (4,'Nilsen', 'Johan', 'Bakken 2', 'Stavanger')<br />
<br />
INSERT INTO Persons (P_Id, LastName, FirstName)<br />
VALUES (5, 'Tjessem', 'Jakob')<br />
<br />
##The UPDATE Statement<br />
<br />
The UPDATE statement is used to update existing records in a table.<br />
<br />
SQL UPDATE Syntax<br />
<br />
UPDATE table_name<br />
SET column1=value, column2=value2,...<br />
WHERE some_column=some_value<br />
Note: Notice the WHERE clause in the UPDATE syntax. The WHERE clause specifies which record or records that should be updated. If you omit the WHERE clause, all records will be updated!<br />
<br />
##The DELETE Statement<br />
<br />
The DELETE statement is used to delete rows in a table.<br />
<br />
SQL DELETE Syntax<br />
<br />
DELETE FROM table_name<br />
WHERE some_column=some_value<br />
Note: Notice the WHERE clause in the DELETE syntax. The WHERE clause specifies which record or records that should be deleted. If you omit the WHERE clause, all records will be deleted!<br />
<br />
Delete All Rows<br />
<br />
It is possible to delete all rows in a table without deleting the table. This means that the table structure, attributes, and indexes will be intact:<br />
<br />
DELETE FROM table_name<br />
<br />
or<br />
<br />
DELETE * FROM table_name<br />
Note: Be very careful when deleting records. You cannot undo this statement!<br />
<br />
###SQL PRIMARY KEY Constraint<br />
<br />
The PRIMARY KEY constraint uniquely identifies each record in a database table.<br />
<br />
Primary keys must contain unique values.<br />
<br />
A primary key column cannot contain NULL values.<br />
<br />
Each table should have a primary key, and each table can have only ONE primary key.<br />
<br />
SQL PRIMARY KEY Constraint on CREATE TABLE<br />
<br />
The following SQL creates a PRIMARY KEY on the "P_Id" column when the "Persons" table is created:<br />
<br />
MySQL:<br />
<br />
CREATE TABLE Persons<br />
(<br />
P_Id int NOT NULL,<br />
LastName varchar(255) NOT NULL,<br />
FirstName varchar(255),<br />
Address varchar(255),<br />
City varchar(255),<br />
PRIMARY KEY (P_Id)<br />
)<br />
SQL Server / Oracle / MS Access:<br />
<br />
CREATE TABLE Persons<br />
(<br />
P_Id int NOT NULL PRIMARY KEY,<br />
LastName varchar(255) NOT NULL,<br />
FirstName varchar(255),<br />
Address varchar(255),<br />
City varchar(255)<br />
)<br />
To allow naming of a PRIMARY KEY constraint, and for defining a PRIMARY KEY constraint on multiple columns, use the following SQL syntax:<br />
<br />
MySQL / SQL Server / Oracle / MS Access:<br />
<br />
CREATE TABLE Persons<br />
(<br />
P_Id int NOT NULL,<br />
LastName varchar(255) NOT NULL,<br />
FirstName varchar(255),<br />
Address varchar(255),<br />
City varchar(255),<br />
CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)<br />
)<br />
Note: In the example above there is only ONE PRIMARY KEY (pk_PersonID). However, the value of the pk_PersonID is made up of two columns (P_Id and LastName).<br />
SQL PRIMARY KEY Constraint on ALTER TABLE<br />
<br />
To create a PRIMARY KEY constraint on the "P_Id" column when the table is already created, use the following SQL:<br />
<br />
MySQL / SQL Server / Oracle / MS Access:<br />
<br />
ALTER TABLE Persons<br />
ADD PRIMARY KEY (P_Id)<br />
To allow naming of a PRIMARY KEY constraint, and for defining a PRIMARY KEY constraint on multiple columns, use the following SQL syntax:<br />
<br />
MySQL / SQL Server / Oracle / MS Access:<br />
<br />
ALTER TABLE Persons<br />
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)<br />
Note: If you use the ALTER TABLE statement to add a primary key, the primary key column(s) must already have been declared to not contain NULL values (when the table was first created).<br />
<br />
To DROP a PRIMARY KEY Constraint<br />
<br />
To drop a PRIMARY KEY constraint, use the following SQL:<br />
<br />
MySQL:<br />
<br />
ALTER TABLE Persons<br />
DROP PRIMARY KEY<br />
SQL Server / Oracle / MS Access:<br />
<br />
ALTER TABLE Persons<br />
DROP CONSTRAINT pk_PersonID<br />
<br />
###SQL FOREIGN KEY Constraint<br />
<br />
A FOREIGN KEY in one table points to a PRIMARY KEY in another table.<br />
<br />
Let's illustrate the foreign key with an example. Look at the following two tables:<br />
<br />
The "Persons" table:<br />
<br />
P_Id<span class="Apple-tab-span" style="white-space: pre;"> </span>LastName<span class="Apple-tab-span" style="white-space: pre;"> </span>FirstName<span class="Apple-tab-span" style="white-space: pre;"> </span>Address<span class="Apple-tab-span" style="white-space: pre;"> </span>City<br />
1<span class="Apple-tab-span" style="white-space: pre;"> </span>Hansen<span class="Apple-tab-span" style="white-space: pre;"> </span>Ola<span class="Apple-tab-span" style="white-space: pre;"> </span>Timoteivn 10<span class="Apple-tab-span" style="white-space: pre;"> </span>Sandnes<br />
2<span class="Apple-tab-span" style="white-space: pre;"> </span>Svendson<span class="Apple-tab-span" style="white-space: pre;"> </span>Tove<span class="Apple-tab-span" style="white-space: pre;"> </span>Borgvn 23<span class="Apple-tab-span" style="white-space: pre;"> </span>Sandnes<br />
3<span class="Apple-tab-span" style="white-space: pre;"> </span>Pettersen<span class="Apple-tab-span" style="white-space: pre;"> </span>Kari<span class="Apple-tab-span" style="white-space: pre;"> </span>Storgt 20<span class="Apple-tab-span" style="white-space: pre;"> </span>Stavanger<br />
The "Orders" table:<br />
<br />
O_Id<span class="Apple-tab-span" style="white-space: pre;"> </span>OrderNo<span class="Apple-tab-span" style="white-space: pre;"> </span>P_Id<br />
1<span class="Apple-tab-span" style="white-space: pre;"> </span>77895<span class="Apple-tab-span" style="white-space: pre;"> </span>3<br />
2<span class="Apple-tab-span" style="white-space: pre;"> </span>44678<span class="Apple-tab-span" style="white-space: pre;"> </span>3<br />
3<span class="Apple-tab-span" style="white-space: pre;"> </span>22456<span class="Apple-tab-span" style="white-space: pre;"> </span>2<br />
4<span class="Apple-tab-span" style="white-space: pre;"> </span>24562<span class="Apple-tab-span" style="white-space: pre;"> </span>1<br />
Note that the "P_Id" column in the "Orders" table points to the "P_Id" column in the "Persons" table.<br />
<br />
The "P_Id" column in the "Persons" table is the PRIMARY KEY in the "Persons" table.<br />
<br />
The "P_Id" column in the "Orders" table is a FOREIGN KEY in the "Orders" table.<br />
<br />
The FOREIGN KEY constraint is used to prevent actions that would destroy links between tables.<br />
<br />
The FOREIGN KEY constraint also prevents that invalid data form being inserted into the foreign key column, because it has to be one of the values contained in the table it points to.<br />
<br />
SQL FOREIGN KEY Constraint on CREATE TABLE<br />
<br />
The following SQL creates a FOREIGN KEY on the "P_Id" column when the "Orders" table is created:<br />
<br />
MySQL:<br />
<br />
CREATE TABLE Orders<br />
(<br />
O_Id int NOT NULL,<br />
OrderNo int NOT NULL,<br />
P_Id int,<br />
PRIMARY KEY (O_Id),<br />
FOREIGN KEY (P_Id) REFERENCES Persons(P_Id)<br />
)<br />
SQL Server / Oracle / MS Access:<br />
<br />
CREATE TABLE Orders<br />
(<br />
O_Id int NOT NULL PRIMARY KEY,<br />
OrderNo int NOT NULL,<br />
P_Id int FOREIGN KEY REFERENCES Persons(P_Id)<br />
)<br />
To allow naming of a FOREIGN KEY constraint, and for defining a FOREIGN KEY constraint on multiple columns, use the following SQL syntax:<br />
<br />
MySQL / SQL Server / Oracle / MS Access:<br />
<br />
CREATE TABLE Orders<br />
(<br />
O_Id int NOT NULL,<br />
OrderNo int NOT NULL,<br />
P_Id int,<br />
PRIMARY KEY (O_Id),<br />
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)<br />
REFERENCES Persons(P_Id)<br />
)<br />
<br />
SQL FOREIGN KEY Constraint on ALTER TABLE<br />
<br />
To create a FOREIGN KEY constraint on the "P_Id" column when the "Orders" table is already created, use the following SQL:<br />
<br />
MySQL / SQL Server / Oracle / MS Access:<br />
<br />
ALTER TABLE Orders<br />
ADD FOREIGN KEY (P_Id)<br />
REFERENCES Persons(P_Id)<br />
To allow naming of a FOREIGN KEY constraint, and for defining a FOREIGN KEY constraint on multiple columns, use the following SQL syntax:<br />
<br />
MySQL / SQL Server / Oracle / MS Access:<br />
<br />
ALTER TABLE Orders<br />
ADD CONSTRAINT fk_PerOrders<br />
FOREIGN KEY (P_Id)<br />
REFERENCES Persons(P_Id)<br />
<br />
To DROP a FOREIGN KEY Constraint<br />
<br />
To drop a FOREIGN KEY constraint, use the following SQL:<br />
<br />
MySQL:<br />
<br />
ALTER TABLE Orders<br />
DROP FOREIGN KEY fk_PerOrders<br />
SQL Server / Oracle / MS Access:<br />
<br />
ALTER TABLE Orders<br />
DROP CONSTRAINT fk_PerOrders<br />
<br />
<br />
###SQL JOIN<br />
<br />
The JOIN keyword is used in an SQL statement to query data from two or more tables, based on a relationship between certain columns in these tables.<br />
<br />
Tables in a database are often related to each other with keys.<br />
<br />
A primary key is a column (or a combination of columns) with a unique value for each row. Each primary key value must be unique within the table. The purpose is to bind data together, across tables, without repeating all of the data in every table.<br />
<br />
Different SQL JOINs<br />
<br />
Before we continue with examples, we will list the types of JOIN you can use, and the differences between them.<br />
<br />
JOIN: Return rows when there is at least one match in both tables<br />
LEFT JOIN: Return all rows from the left table, even if there are no matches in the right table<br />
RIGHT JOIN: Return all rows from the right table, even if there are no matches in the left table<br />
FULL JOIN: Return rows when there is a match in one of the tables<br />
<br />
###SQL INNER JOIN Keyword<br />
<br />
The INNER JOIN keyword return rows when there is at least one match in both tables.<br />
<br />
SQL INNER JOIN Syntax<br />
<br />
SELECT column_name(s)<br />
FROM table_name1<br />
INNER JOIN table_name2<br />
ON table_name1.column_name=table_name2.column_name<br />
PS: INNER JOIN is the same as JOIN.<br />
<br />
SQL INNER JOIN Example<br />
<br />
The "Persons" table:<br />
<br />
P_Id<span class="Apple-tab-span" style="white-space: pre;"> </span>LastName<span class="Apple-tab-span" style="white-space: pre;"> </span>FirstName<span class="Apple-tab-span" style="white-space: pre;"> </span>Address<span class="Apple-tab-span" style="white-space: pre;"> </span>City<br />
1<span class="Apple-tab-span" style="white-space: pre;"> </span>Hansen<span class="Apple-tab-span" style="white-space: pre;"> </span>Ola<span class="Apple-tab-span" style="white-space: pre;"> </span>Timoteivn 10<span class="Apple-tab-span" style="white-space: pre;"> </span>Sandnes<br />
2<span class="Apple-tab-span" style="white-space: pre;"> </span>Svendson<span class="Apple-tab-span" style="white-space: pre;"> </span>Tove<span class="Apple-tab-span" style="white-space: pre;"> </span>Borgvn 23<span class="Apple-tab-span" style="white-space: pre;"> </span>Sandnes<br />
3<span class="Apple-tab-span" style="white-space: pre;"> </span>Pettersen<span class="Apple-tab-span" style="white-space: pre;"> </span>Kari<span class="Apple-tab-span" style="white-space: pre;"> </span>Storgt 20<span class="Apple-tab-span" style="white-space: pre;"> </span>Stavanger<br />
The "Orders" table:<br />
<br />
O_Id<span class="Apple-tab-span" style="white-space: pre;"> </span>OrderNo<span class="Apple-tab-span" style="white-space: pre;"> </span>P_Id<br />
1<span class="Apple-tab-span" style="white-space: pre;"> </span>77895<span class="Apple-tab-span" style="white-space: pre;"> </span>3<br />
2<span class="Apple-tab-span" style="white-space: pre;"> </span>44678<span class="Apple-tab-span" style="white-space: pre;"> </span>3<br />
3<span class="Apple-tab-span" style="white-space: pre;"> </span>22456<span class="Apple-tab-span" style="white-space: pre;"> </span>1<br />
4<span class="Apple-tab-span" style="white-space: pre;"> </span>24562<span class="Apple-tab-span" style="white-space: pre;"> </span>1<br />
5<span class="Apple-tab-span" style="white-space: pre;"> </span>34764<span class="Apple-tab-span" style="white-space: pre;"> </span>15<br />
Now we want to list all the persons with any orders.<br />
<br />
We use the following SELECT statement:<br />
<br />
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo<br />
FROM Persons<br />
INNER JOIN Orders<br />
ON Persons.P_Id=Orders.P_Id<br />
ORDER BY Persons.LastName<br />
The result-set will look like this:<br />
<br />
LastName<span class="Apple-tab-span" style="white-space: pre;"> </span>FirstName<span class="Apple-tab-span" style="white-space: pre;"> </span>OrderNo<br />
Hansen<span class="Apple-tab-span" style="white-space: pre;"> </span>Ola<span class="Apple-tab-span" style="white-space: pre;"> </span>22456<br />
Hansen<span class="Apple-tab-span" style="white-space: pre;"> </span>Ola<span class="Apple-tab-span" style="white-space: pre;"> </span>24562<br />
Pettersen<span class="Apple-tab-span" style="white-space: pre;"> </span>Kari<span class="Apple-tab-span" style="white-space: pre;"> </span>77895<br />
Pettersen<span class="Apple-tab-span" style="white-space: pre;"> </span>Kari<span class="Apple-tab-span" style="white-space: pre;"> </span>44678<br />
The INNER JOIN keyword return rows when there is at least one match in both tables. If there are rows in "Persons" that do not have matches in "Orders", those rows will NOT be listed.<br />
<br />
###LEFT JOIN<br />
<br />
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo<br />
FROM Persons<br />
LEFT JOIN Orders<br />
ON Persons.P_Id=Orders.P_Id<br />
ORDER BY Persons.LastName<br />
The result-set will look like this:<br />
<br />
LastName<span class="Apple-tab-span" style="white-space: pre;"> </span>FirstName<span class="Apple-tab-span" style="white-space: pre;"> </span>OrderNo<br />
Hansen<span class="Apple-tab-span" style="white-space: pre;"> </span>Ola<span class="Apple-tab-span" style="white-space: pre;"> </span>22456<br />
Hansen<span class="Apple-tab-span" style="white-space: pre;"> </span>Ola<span class="Apple-tab-span" style="white-space: pre;"> </span>24562<br />
Pettersen<span class="Apple-tab-span" style="white-space: pre;"> </span>Kari<span class="Apple-tab-span" style="white-space: pre;"> </span>77895<br />
Pettersen<span class="Apple-tab-span" style="white-space: pre;"> </span>Kari<span class="Apple-tab-span" style="white-space: pre;"> </span>44678<br />
Svendson<span class="Apple-tab-span" style="white-space: pre;"> </span>Tove<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
The LEFT JOIN keyword returns all the rows from the left table (Persons), even if there are no matches in the right table (Orders).<br />
<br />
###RIGHT JOIN<br />
<br />
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo<br />
FROM Persons<br />
RIGHT JOIN Orders<br />
ON Persons.P_Id=Orders.P_Id<br />
ORDER BY Persons.LastName<br />
The result-set will look like this:<br />
<br />
LastName<span class="Apple-tab-span" style="white-space: pre;"> </span>FirstName<span class="Apple-tab-span" style="white-space: pre;"> </span>OrderNo<br />
Hansen<span class="Apple-tab-span" style="white-space: pre;"> </span>Ola<span class="Apple-tab-span" style="white-space: pre;"> </span>22456<br />
Hansen<span class="Apple-tab-span" style="white-space: pre;"> </span>Ola<span class="Apple-tab-span" style="white-space: pre;"> </span>24562<br />
Pettersen<span class="Apple-tab-span" style="white-space: pre;"> </span>Kari<span class="Apple-tab-span" style="white-space: pre;"> </span>77895<br />
Pettersen<span class="Apple-tab-span" style="white-space: pre;"> </span>Kari<span class="Apple-tab-span" style="white-space: pre;"> </span>44678<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>34764<br />
The RIGHT JOIN keyword returns all the rows from the right table (Orders), even if there are no matches in the left table (Persons).<br />
<br />
###FULL JOIN<br />
<br />
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo<br />
FROM Persons<br />
FULL JOIN Orders<br />
ON Persons.P_Id=Orders.P_Id<br />
ORDER BY Persons.LastName<br />
The result-set will look like this:<br />
<br />
LastName<span class="Apple-tab-span" style="white-space: pre;"> </span>FirstName<span class="Apple-tab-span" style="white-space: pre;"> </span>OrderNo<br />
Hansen<span class="Apple-tab-span" style="white-space: pre;"> </span>Ola<span class="Apple-tab-span" style="white-space: pre;"> </span>22456<br />
Hansen<span class="Apple-tab-span" style="white-space: pre;"> </span>Ola<span class="Apple-tab-span" style="white-space: pre;"> </span>24562<br />
Pettersen<span class="Apple-tab-span" style="white-space: pre;"> </span>Kari<span class="Apple-tab-span" style="white-space: pre;"> </span>77895<br />
Pettersen<span class="Apple-tab-span" style="white-space: pre;"> </span>Kari<span class="Apple-tab-span" style="white-space: pre;"> </span>44678<br />
Svendson<span class="Apple-tab-span" style="white-space: pre;"> </span>Tove<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> <span class="Apple-tab-span" style="white-space: pre;"> </span>34764<br />
The FULL JOIN keyword returns all the rows from the left table (Persons), and all the rows from the right table (Orders). If there are rows in "Persons" that do not have matches in "Orders", or if there are rows in "Orders" that do not have matches in "Persons", those rows will be listed as well.<br />
<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-27121090395547994472012-06-06T07:52:00.000+05:302012-06-06T07:52:00.444+05:30GIST NOTES 19 - UML<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 19 - UML</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books/sources on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
<a href="http://www.ibm.com/developerworks/rational/library/769.html#N100D7">http://www.ibm.com/developerworks/rational/library/769.html#N100D7</a><br />
<br />
>Class diagram represents the static structure of the system<br />
>Classes in the class diagram can represent logical things or actual implementing classes<br />
>In my experience, almost every developer knows what this diagram is, yet I find that most programmers draw the relationship lines incorrectly. For a class diagram like the one in Figure 3, you should draw the inheritance relationship1 using a line with an arrowhead at the top pointing to the super class, and the arrowhead should be a completed triangle. [Note: For more information on inheritance and other object-oriented principles, see the Java tutorial What Is Inheritance?] An association relationship should be a solid line if both classes are aware of each other and a line with an open arrowhead if the association is known by only one of the classes.<br />
<br />
Figure 3: A complete class diagram, including the class object shown in Figure 2<br />
<br />
Larger view of Figure 3.<br />
In Figure 3, we see both the inheritance relationship and two association relationships. The CDSalesReport class inherits from the Report class. A CDSalesReport is associated with one CD, but the CD class doesn't know anything about the CDSalesReport class. The CD and the Band classes both know about each other, and both classes can be associated to one or more of each other.<br />
<br />
>Use-case diagram<br />
A use case illustrates a unit of functionality provided by the system. The main purpose of the use-case diagram is to help development teams visualize the functional requirements of a system, including the relationship of "actors" (human beings who will interact with the system) to essential processes, as well as the relationships among different use cases.<br />
<br />
>Sequence diagram<br />
Sequence diagrams show a detailed flow for a specific use case or even just part of a specific use case. They are almost self explanatory; they show the calls between the different objects in their sequence and can show, at a detailed level, different calls to different objects.<br />
A sequence diagram has two dimensions: The vertical dimension shows the sequence of messages/calls in the time order that they occur; the horizontal dimension shows the object instances to which the messages are sent.<br />
<br />
>Statechart diagram<br />
The statechart diagram models the different states that a class can be in and how that class transitions from state to state. It can be argued that every class has a state, but that every class shouldn't have a statechart diagram. Only classes with "interesting" states — that is, classes with three or more potential states during system activity — should be modeled.<br />
<br />
>Activity diagram<br />
Activity diagrams show the procedural flow of control between two or more class objects while processing an activity. Activity diagrams can be used to model higher-level business process at the business unit level, or to model low-level internal class actions. In my experience, activity diagrams are best used to model higher-level processes, such as how the company is currently doing business, or how it would like to do business. This is because activity diagrams are "less technical" in appearance, compared to sequence diagrams, and business-minded people tend to understand them more quickly.<br />
<br />
>Component diagram<br />
A component diagram provides a physical view of the system. Its purpose is to show the dependencies that the software has on the other software components (e.g., software libraries) in the system. The diagram can be shown at a very high level, with just the large-grain components, or it can be shown at the component package level. [Note: The phrase component package level is a programming language-neutral way of referring to class container levels such as .NET's namespaces (e.g., System.Web.UI) or Java's packages (e.g., java.util).]<br />
<br />
>Deployment diagram<br />
The deployment diagram shows how a system will be physically deployed in the hardware environment. Its purpose is to show where the different components of the system will physically run and how they will communicate with each other. Since the diagram models the physical runtime, a system's production staff will make considerable use of this diagram.<br />
The notation in a deployment diagram includes the notation elements used in a component diagram, with a couple of additions, including the concept of a node. A node represents either a physical machine or a virtual machine node (e.g., a mainframe node). To model a node, simply draw a three-dimensional cube with the name of the node at the top of the cube. Use the naming convention used in sequence diagrams: [instance name] : [instance type] (e.g., "w3reporting.myco.com : Application Server").<br />
<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-16376057766088054742012-06-05T07:50:00.000+05:302012-07-17T23:17:45.297+05:30GIST NOTES 18 - XML<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 18 - XML</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books/sources on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
>The Java API for XML Processing (JAXP)<br />
>Simple API for XML (SAX), as developed cooperatively by the members of the XML-DEV mailing list.<br />
>SAX (Simple API for XML) is an event-based sequential access parser API developed by the XML-DEV mailing list for XML documents.[1] SAX provides a mechanism for reading data from an XML document that is an alternative to that provided by the Document Object Model (DOM). Where the DOM operates on the document as a whole, SAX parsers operate on each piece of the XML document sequentially.<br />
<br />
>Benefits<br />
<br />
SAX parsers have certain benefits over DOM-style parsers. The quantity of memory that a SAX parser must use in order to function is typically much smaller than that of a DOM parser. DOM parsers must have the entire tree in memory before any processing can begin, so the amount of memory used by a DOM parser depends entirely on the size of the input data. The memory footprint of a SAX parser, by contrast, is based only on the maximum depth of the XML file (the maximum depth of the XML tree) and the maximum data stored in XML attributes on a single XML element. Both of these are always smaller than the size of the parsed tree itself.<br />
<br />
Because of the event-driven nature of SAX, processing documents can often be faster than DOM-style parsers. Memory allocation takes time, so the larger memory footprint of the DOM is also a performance issue.<br />
<br />
Due to the nature of DOM, streamed reading from disk is impossible. Processing XML documents larger than main memory is also impossible with DOM parsers, but can be done with SAX parsers. However, DOM parsers may make use of disk space as memory to sidestep this limitation. [4]<br />
<br />
>SAX processor generates events on start and end of element and text nodes with attributes reported along<br />
<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-25834981914929696892012-06-04T07:48:00.000+05:302012-07-17T23:17:45.307+05:30GIST NOTES 17 - Java Serialization<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 17 - Java Serialization</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books/sources on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
>Serialization - convert an object into bit streams so that it can be saved in a file or sent over the network to another machine<br />
<br />
<br />
>Special handling is required for arrays, enum constants, and objects of type Class, ObjectStreamClass, and String. Other objects must implement either the Serializable or the Externalizable interface to be saved in or restored from a stream.<br />
<br />
>Enum constants are serialized differently than ordinary serializable or externalizable objects. The serialized form of an enum constant consists solely of its name; field values of the constant are not transmitted. To serialize an enum constant, ObjectOutputStream writes the string returned by the constant's name method. Like other serializable or externalizable objects, enum constants can function as the targets of back references appearing subsequently in the serialization stream. The process by which enum constants are serialized cannot be customized; any class-specific writeObject and writeReplace methods defined by enum types are ignored during serialization. Similarly, any serialPersistentFields or serialVersionUID field declarations are also ignored--all enum types have a fixed serialVersionUID of 0L.<br />
<br />
>The flush method is used to empty any buffers being held by the stream and to forward the flush to the underlying stream. The drain method may be used by subclassers to empty only the ObjectOutputStream's buffers without forcing the underlying stream to be flushed.<br />
<br />
>Each subclass of a serializable object may define its own writeObject method. If a class does not implement the method, the default serialization provided by defaultWriteObject will be used. When implemented, the class is only responsible for writing its own fields, not those of its supertypes or subtypes.<br />
<br />
>Note - The ObjectInputStream constructor blocks until it completes reading the serialization stream header. Code which waits for an ObjectInputStream to be constructed before creating the corresponding ObjectOutputStream for that stream will deadlock, since the ObjectInputStream constructor will block until a header is written to the stream, and the header will not be written to the stream until the ObjectOutputStream constructor executes. This problem can be resolved by creating the ObjectOutputStream before the ObjectInputStream, or otherwise removing the timing dependency between completion of ObjectInputStream construction and the creation of the ObjectOutputStream.<br />
<br />
>The registerValidation method can be called to request a callback when the entire graph(object graph) has been restored but before the object is returned to the original caller of readObject. The order of validate callbacks can be controlled using the priority. Callbacks registered with higher values are called before those with lower values. The object to be validated must support the ObjectInputValidation interface and implement the validateObject method. It is only correct to register validations during a call to a class's readObject method. Otherwise, a NotActiveException is thrown. If the callback object supplied to registerValidation is null, an InvalidObjectException is thrown.<br />
<br />
>The readObject method of the class, if implemented, is responsible for restoring the state of the class. The values of every field of the object whether transient or not, static or not are set to the default value for the fields type. Either ObjectInputStream's defaultReadObject or readFields method must be called once (and only once) before reading any optional data written by the corresponding writeObject method; even if no optional data is read, defaultReadObject or readFields must still be invoked once. If the readObject method of the class attempts to read more data than is present in the optional part of the stream for this class, the stream will return -1 for bytewise reads, throw an EOFException for primitive data reads (e.g., readInt, readFloat), or throw an OptionalDataException with the eof field set to true for object reads.<br />
<br />
>Reading an object from the ObjectInputStream is analogous to creating a new object. Just as a new object's constructors are invoked in the order from the superclass to the subclass, an object being read from a stream is deserialized from superclass to subclass. The readObject or readObjectNoData method is called instead of the constructor for each Serializable subclass during deserialization.<br />
<br />
>One last similarity between a constructor and a readObject method is that both provide the opportunity to invoke a method on an object that is not fully constructed. Any overridable (neither private, static nor final) method called while an object is being constructed can potentially be overridden by a subclass. Methods called during the construction phase of an object are resolved by the actual type of the object, not the type currently being initialized by either its constructor or readObject/readObjectNoData method. Therefore, calling an overridable method from within a readObject or readObjectNoData method may result in the unintentional invocation of a subclass method before the superclass has been fully initialized.<br />
<br />
>For serializable objects, the readObjectNoData method allows a class to control the initialization of its own fields in the event that a subclass instance is deserialized and the serialization stream does not list the class in question as a superclass of the deserialized object. This may occur in cases where the receiving party uses a different version of the deserialized instance's class than the sending party, and the receiver's version extends classes that are not extended by the sender's version. This may also occur if the serialization stream has been tampered; hence, readObjectNoData is useful for initializing deserialized objects properly despite a "hostile" or incomplete source stream.<br />
<br />
private void readObjectNoData() throws ObjectStreamException;<br />
<br />
<br />
>A new stream protocol version has been introduced in JDK 1.2 to correct a problem with Externalizable objects. The old definition of Externalizable objects required the local virtual machine to find a readExternal method to be able to properly read an Externalizable object from the stream. The new format adds enough information to the stream protocol so serialization can skip an Externalizable object when the local readExternal method is not available. Due to class evolution rules, serialization must be able to skip an Externalizable object in the input stream if there is not a mapping for the object using the local classes.<br />
<br />
Due to the format change, JDK 1.1.6 and earlier releases are not able to read the new format. StreamCorruptedException is thrown when JDK 1.1.6 or earlier attempts to read an Externalizable object from a stream written in PROTOCOL_VERSION_2. Compatibility issues are discussed in more detail in Section 6.3, "Stream Protocol Versions."<br />
<br />
>The ObjectStreamClass.getSerialVersionUID method returns the serialVersionUID of this class. Refer to Section 4.6, "Stream Unique Identifiers." If not specified by the class, the value returned is a hash computed from the class's name, interfaces, methods, and fields using the Secure Hash Algorithm (SHA) as defined by the National Institute of Standards.<br />
<br />
>4.2 Dynamic Proxy Class Descriptors<br />
<br />
ObjectStreamClass descriptors are also used to provide information about dynamic proxy classes (e.g., classes obtained via calls to the getProxyClass method of java.lang.reflect.Proxy) saved in a serialization stream. A dynamic proxy class itself has no serializable fields and a serialVersionUID of 0L. In other words, when the Class object for a dynamic proxy class is passed to the static lookup method of ObjectStreamClass, the returned ObjectStreamClass instance will have the following properties:<br />
<br />
Invoking its getSerialVersionUID method will return 0L.<br />
Invoking its getFields method will return an array of length zero.<br />
Invoking its getField method with any String argument will return null.<br />
<br />
>4.3 Serialized Form<br />
<br />
The serialized form of an ObjectStreamClass instance depends on whether or not the Class object it represents is serializable, externalizable, or a dynamic proxy class.<br />
<br />
When an ObjectStreamClass instance that does not represent a dynamic proxy class is written to the stream, it writes the class name and serialVersionUID, flags, and the number of fields. Depending on the class, additional information may be written:<br />
<br />
For non-serializable classes, the number of fields is always zero. Neither the SC_SERIALIZABLE nor the SC_EXTERNALIZABLE flag bits are set.<br />
For serializable classes, the SC_SERIALIZABLE flag is set, the number of fields counts the number of serializable fields and is followed by a descriptor for each serializable field. The descriptors are written in canonical order. The descriptors for primitive typed fields are written first sorted by field name followed by descriptors for the object typed fields sorted by field name. The names are sorted using String.compareTo. For details of the format, refer to Section 6.4, "Grammar for the Stream Format".<br />
For externalizable classes, flags includes the SC_EXTERNALIZABLE flag, and the number of fields is always zero.<br />
For enum types, flags includes the SC_ENUM flag, and the number of fields is always zero.<br />
When an ObjectOutputStream serializes the ObjectStreamClass descriptor for a dynamic proxy class, as determined by passing its Class object to the isProxyClass method of java.lang.reflect.Proxy, it writes the number of interfaces that the dynamic proxy class implements, followed by the interface names. Interfaces are listed in the order that they are returned by invoking the getInterfaces method on the Class object of the dynamic proxy class.<br />
<br />
The serialized representations of ObjectStreamClass descriptors for dynamic proxy classes and non-dynamic proxy classes are differentiated through the use of different typecodes (TC_PROXYCLASSDESC and TC_CLASSDESC, respectively); for a more detailed specification of the grammar, see Section 6.4, "Grammar for the Stream Format".<br />
<br />
>'serialver -show' shows a GUI that lets to find out serialVersionUID of any class<br />
<br />
>4.6 Stream Unique Identifiers<br />
<br />
Each versioned class must identify the original class version for which it is capable of writing streams and from which it can read. For example, a versioned class must declare:<br />
<br />
private static final long serialVersionUID = 3487495895819393L;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
The stream-unique identifier is a 64-bit hash of the class name, interface class names, methods, and fields. The value must be declared in all versions of a class except the first. It may be declared in the original class but is not required. The value is fixed for all compatible classes. If the SUID is not declared for a class, the value defaults to the hash for that class. The serialVersionUID for dynamic proxy classes and enum types always have the value 0L. Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes.<br />
<br />
Note - It is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected serialVersionUID conflicts during deserialization, causing deserialization to fail.<br />
<br />
>The serialVersionUID is computed using the signature of a stream of bytes that reflect the class definition. The National Institute of Standards and Technology (NIST) Secure Hash Algorithm (SHA-1) is used to compute a signature for the stream. The first two 32-bit quantities are used to form a 64-bit hash. A java.lang.DataOutputStream is used to convert primitive data types to a sequence of bytes. The values input to the stream are defined by the Java Virtual Machine (VM) specification for classes. Class modifiers may include the ACC_PUBLIC, ACC_FINAL, ACC_INTERFACE, and ACC_ABSTRACT flags; other flags are ignored and do not affect serialVersionUID computation. Similarly, for field modifiers, only the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when computing serialVersionUID values. For constructor and method modifiers, only the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT flags are used. Names and descriptors are written in the format used by the java.io.DataOutputStream.writeUTF method.<br />
<br />
The sequence of items in the stream is as follows:<br />
<br />
<br />
The class name.<br />
The class modifiers written as a 32-bit integer.<br />
The name of each interface sorted by name.<br />
For each field of the class sorted by field name (except private static and private transient fields:<br />
The name of the field.<br />
The modifiers of the field written as a 32-bit integer.<br />
The descriptor of the field.<br />
If a class initializer exists, write out the following:<br />
The name of the method, <clinit>.</clinit><br />
The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.<br />
The descriptor of the method, ()V.<br />
For each non-private constructor sorted by method name and signature:<br />
The name of the method, <init>.</init><br />
The modifiers of the method written as a 32-bit integer.<br />
The descriptor of the method.<br />
For each non-private method sorted by method name and signature:<br />
The name of the method.<br />
The modifiers of the method written as a 32-bit integer.<br />
The descriptor of the method.<br />
The SHA-1 algorithm is executed on the stream of bytes produced by DataOutputStream and produces five 32-bit values sha[0..4].<br />
The hash value is assembled from the first and second 32-bit values of the SHA-1 message digest. If the result of the message digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named sha, the hash value would be computed as follows:<br />
long hash = ((sha[0] >>> 24) & 0xFF) |<br />
((sha[0] >>> 16) & 0xFF) << 8 |<br />
((sha[0] >>> 8) & 0xFF) << 16 |<br />
((sha[0] >>> 0) & 0xFF) << 24 |<br />
((sha[1] >>> 24) & 0xFF) << 32 |<br />
((sha[1] >>> 16) & 0xFF) << 40 |<br />
((sha[1] >>> 8) & 0xFF) << 48 |<br />
((sha[1] >>> 0) & 0xFF) << 56;<br />
<br />
Versioning<br />
----------<br />
>Versioning raises some fundamental questions about the identity of a class, including what constitutes a compatible change. A compatible change is a change that does not affect the contract between the class and its callers.<br />
<br />
>5.2<span class="Apple-tab-span" style="white-space: pre;"> </span> Goals<br />
<br />
The goals are to:<br />
<br />
Support bidirectional communication between different versions of a class operating in different virtual machines by:<br />
Defining a mechanism that allows Java classes to read streams written by older versions of the same class.<br />
Defining a mechanism that allows Java classes to write streams intended to be read by older versions of the same class.<br />
Provide default serialization for persistence and for RMI.<br />
Perform well and produce compact streams in simple cases, so that RMI can use serialization.<br />
Be able to identify and load classes that match the exact class used to write the stream.<br />
Keep the overhead low for nonversioned classes.<br />
Use a stream format that allows the traversal of the stream without having to invoke methods specific to the objects saved in the stream.<br />
<br />
>The following are the principle aspects of the design for versioning of serialized object streams.<br />
<br />
The default serialization mechanism will use a symbolic model for binding the fields in the stream to the fields in the corresponding class in the virtual machine.<br />
Each class referenced in the stream will uniquely identify itself, its supertype, and the types and names of each serializable field written to the stream. The fields are ordered with the primitive types first sorted by field name, followed by the object fields sorted by field name.<br />
Two types of data may occur in the stream for each class: required data (corresponding directly to the serializable fields of the object); and optional data (consisting of an arbitrary sequence of primitives and objects). The stream format defines how the required and optional data occur in the stream so that the whole class, the required, or the optional parts can be skipped if necessary.<br />
The required data consists of the fields of the object in the order defined by the class descriptor.<br />
The optional data is written to the stream and does not correspond directly to fields of the class. The class itself is responsible for the length, types, and versioning of this optional information.<br />
If defined for a class, the writeObject/readObject methods supersede the default mechanism to write/read the state of the class. These methods write and read the optional data for a class. The required data is written by calling defaultWriteObject and read by calling defaultReadObject.<br />
The stream format of each class is identified by the use of a Stream Unique Identifier (SUID). By default, this is the hash of the class. All later versions of the class must declare the Stream Unique Identifier (SUID) that they are compatible with. This guards against classes with the same name that might inadvertently be identified as being versions of a single class.<br />
Subtypes of ObjectOutputStream and ObjectInputStream may include their own information identifying the class using the annotateClass method; for example, MarshalOutputStream embeds the URL of the class.<br />
<br />
<br />
>5.6.1<span class="Apple-tab-span" style="white-space: pre;"> </span> Incompatible Changes<br />
<br />
Incompatible changes to classes are those changes for which the guarantee of interoperability cannot be maintained. The incompatible changes that may occur while evolving a class are:<br />
<br />
Deleting fields - If a field is deleted in a class, the stream written will not contain its value. When the stream is read by an earlier class, the value of the field will be set to the default value because no value is available in the stream. However, this default value may adversely impair the ability of the earlier version to fulfill its contract.<br />
Moving classes up or down the hierarchy - This cannot be allowed since the data in the stream appears in the wrong sequence.<br />
Changing a nonstatic field to static or a nontransient field to transient - When relying on default serialization, this change is equivalent to deleting a field from the class. This version of the class will not write that data to the stream, so it will not be available to be read by earlier versions of the class. As when deleting a field, the field of the earlier version will be initialized to the default value, which can cause the class to fail in unexpected ways.<br />
Changing the declared type of a primitive field - Each version of the class writes the data with its declared type. Earlier versions of the class attempting to read the field will fail because the type of the data in the stream does not match the type of the field.<br />
Changing the writeObject or readObject method so that it no longer writes or reads the default field data or changing it so that it attempts to write it or read it when the previous version did not. The default field data must consistently either appear or not appear in the stream.<br />
Changing a class from Serializable to Externalizable or vice versa is an incompatible change since the stream will contain data that is incompatible with the implementation of the available class.<br />
Changing a class from a non-enum type to an enum type or vice versa since the stream will contain data that is incompatible with the implementation of the available class.<br />
Removing either Serializable or Externalizable is an incompatible change since when written it will no longer supply the fields needed by older versions of the class.<br />
Adding the writeReplace or readResolve method to a class is incompatible if the behavior would produce an object that is incompatible with any older version of the class.<br />
<br />
<br />
>5.6.2<span class="Apple-tab-span" style="white-space: pre;"> </span> Compatible Changes<br />
<br />
The compatible changes to a class are handled as follows:<br />
<br />
Adding fields - When the class being reconstituted has a field that does not occur in the stream, that field in the object will be initialized to the default value for its type. If class-specific initialization is needed, the class may provide a readObject method that can initialize the field to nondefault values.<br />
Adding classes - The stream will contain the type hierarchy of each object in the stream. Comparing this hierarchy in the stream with the current class can detect additional classes. Since there is no information in the stream from which to initialize the object, the class's fields will be initialized to the default values.<br />
Removing classes - Comparing the class hierarchy in the stream with that of the current class can detect that a class has been deleted. In this case, the fields and objects corresponding to that class are read from the stream. Primitive fields are discarded, but the objects referenced by the deleted class are created, since they may be referred to later in the stream. They will be garbage-collected when the stream is garbage-collected or reset.<br />
Adding writeObject/readObject methods - If the version reading the stream has these methods then readObject is expected, as usual, to read the required data written to the stream by the default serialization. It should call defaultReadObject first before reading any optional data. The writeObject method is expected as usual to call defaultWriteObject to write the required data and then may write optional data.<br />
Removing writeObject/readObject methods - If the class reading the stream does not have these methods, the required data will be read by default serialization, and the optional data will be discarded.<br />
Adding java.io.Serializable - This is equivalent to adding types. There will be no values in the stream for this class so its fields will be initialized to default values. The support for subclassing nonserializable classes requires that the class's supertype have a no-arg constructor and the class itself will be initialized to default values. If the no-arg constructor is not available, the InvalidClassException is thrown.<br />
Changing the access to a field - The access modifiers public, package, protected, and private have no effect on the ability of serialization to assign values to the fields.<br />
Changing a field from static to nonstatic or transient to nontransient - When relying on default serialization to compute the serializable fields, this change is equivalent to adding a field to the class. The new field will be written to the stream but earlier classes will ignore the value since serialization will not assign values to static or transient fields.<br />
<br />
<br />
Behavior when both writeObject/readObject and writeReplace/readResolve methods present<br />
-----------------------------------------------------------------------------------<br />
The call sequence follows this order: Serialized object class is Seri and its replacement object is SeriR (SeriR extends Seri)<br />
<br />
call to writeReplace():Seri<br />
call to writeReplace():SeriR<br />
call to writeObject():SeriR<br />
call to writeReplace():SeriR<br />
call to writeObject():SeriR<br />
call to readObject():SeriR<br />
call to readObject():SeriR<br />
call to readResolve():SeriR<br />
call to readResolve():SeriR<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#readResolve() of Seri class is never called<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#object returned by writeReplace() can be ignored in writeObject() and something else can be written to the stream<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#writeObject() has the final say in what goes to file or stream<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#since readResolve() is called finally, anything that was read from file can be overridden<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#readResolve() has the final say in what comes out of serialization<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#note that both writeReplace and readResolve should return Object type; these methods can have any access modifiers<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#readObject/writeObject should be private for them to be called during serialization/deserialization<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
>Externalizable class should explicitly declare a default no-arg constructor, otherwise runtime exception(InvalidClassException) is thrown during serialization<br />
<br />
>By extending ObjectOutputStream/ObjectInputStream, you can have your own custom streams<br />
>Object replacement, resolution, protection of sensitive data, JVM wide security policy implementation and such functions can be moved to such custom streams; this makes the user of the custom streams transparent to such complexities<br />
>For example, a custom stream can wrap every object or primitive written into it with a wrapper class that provides uniform custom encryption protection<br />
<br />
What's the difference between the SUID (Stream Unique IDentifier) and the private static member serialVersionUID?<br />
<br />
Answer:<br />
The SUID is one of a number of things that the serialization protocol writes to the stream in addition to the serialized object (other things include a magic number and the fully- qualified class name of the object). SUID is not the same as the static variable serialVersionUID, although SUID is computed using that field, if it exists. In psuedocode,<br />
<br />
if (serialVersionUID is defined) then<br />
SUID is set equal to serialVersionUID<br />
else<br />
SUID is computed algoritmically<br />
Because serialVersionUID is a static member, it is not written to the stream as part of the serialized object. Instead, serialization uses the serialVersionUID to compute the SUID. The SUID is then sent to the stream as part of the stream protocol, not as part of the object definition.<br />
Deserializing requires two things:<br />
<br />
The serialized object. This does not include the static member serialVersionUID, but it does include the SUID, fully-qualified class name, etc.<br />
The .class file. This does include the static members.<br />
When deserializing, the SUID embedded in the object input stream is compared to the SUID computed from the local .class file according to the psuedocode above. If the SUIDs are equal, then the serialized object is compatible with the class file definition.<br />
<br />
<b>Reference</b>: JDK Docs and Tutorials<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-43381167224760959942012-06-03T07:44:00.000+05:302012-07-17T23:17:45.331+05:30GIST NOTES 16 - Java Reflections<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 16 - Java Reflections</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
public class Proxy<br />
extends Object<br />
implements Serializable<br />
Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.<br />
To create a proxy for some interface Foo:<br />
<br />
InvocationHandler handler = new MyInvocationHandler(...);<br />
Class proxyClass = Proxy.getProxyClass(<br />
Foo.class.getClassLoader(), new Class[] { Foo.class });<br />
Foo f = (Foo) proxyClass.<br />
getConstructor(new Class[] { InvocationHandler.class }).<br />
newInstance(new Object[] { handler });<br />
<br />
or more simply:<br />
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),<br />
new Class[] { Foo.class },<br />
handler);<br />
<br />
A dynamic proxy class (simply referred to as a proxy class below) is a class that implements a list of interfaces specified at runtime when the class is created, with behavior as described below. A proxy interface is such an interface that is implemented by a proxy class. A proxy instance is an instance of a proxy class. Each proxy instance has an associated invocation handler object, which implements the interface InvocationHandler. A method invocation on a proxy instance through one of its proxy interfaces will be dispatched to the invoke method of the instance's invocation handler, passing the proxy instance, a java.lang.reflect.Method object identifying the method that was invoked, and an array of type Object containing the arguments. The invocation handler processes the encoded method invocation as appropriate and the result that it returns will be returned as the result of the method invocation on the proxy instance.<br />
<br />
A proxy class has the following properties:<br />
<br />
Proxy classes are public, final, and not abstract.<br />
The unqualified name of a proxy class is unspecified. The space of class names that begin with the string "$Proxy" should be, however, reserved for proxy classes.<br />
A proxy class extends java.lang.reflect.Proxy.<br />
A proxy class implements exactly the interfaces specified at its creation, in the same order.<br />
If a proxy class implements a non-public interface, then it will be defined in the same package as that interface. Otherwise, the package of a proxy class is also unspecified. Note that package sealing will not prevent a proxy class from being successfully defined in a particular package at runtime, and neither will classes already defined by the same class loader and the same package with particular signers.<br />
Since a proxy class implements all of the interfaces specified at its creation, invoking getInterfaces on its Class object will return an array containing the same list of interfaces (in the order specified at its creation), invoking getMethods on its Class object will return an array of Method objects that include all of the methods in those interfaces, and invoking getMethod will find methods in the proxy interfaces as would be expected.<br />
The Proxy.isProxyClass method will return true if it is passed a proxy class-- a class returned by Proxy.getProxyClass or the class of an object returned by Proxy.newProxyInstance-- and false otherwise.<br />
The java.security.ProtectionDomain of a proxy class is the same as that of system classes loaded by the bootstrap class loader, such as java.lang.Object, because the code for a proxy class is generated by trusted system code. This protection domain will typically be granted java.security.AllPermission.<br />
Each proxy class has one public constructor that takes one argument, an implementation of the interface InvocationHandler, to set the invocation handler for a proxy instance. Rather than having to use the reflection API to access the public constructor, a proxy instance can be also be created by calling the Proxy.newProxyInstance method, which combines the actions of calling Proxy.getProxyClass with invoking the constructor with an invocation handler.<br />
A proxy instance has the following properties:<br />
<br />
Given a proxy instance proxy and one of the interfaces implemented by its proxy class Foo, the following expression will return true:<br />
proxy instanceof Foo<br />
<br />
and the following cast operation will succeed (rather than throwing a ClassCastException):<br />
(Foo) proxy<br />
<br />
Each proxy instance has an associated invocation handler, the one that was passed to its constructor. The static Proxy.getInvocationHandler method will return the invocation handler associated with the proxy instance passed as its argument.<br />
An interface method invocation on a proxy instance will be encoded and dispatched to the invocation handler's invoke method as described in the documentation for that method.<br />
An invocation of the hashCode, equals, or toString methods declared in java.lang.Object on a proxy instance will be encoded and dispatched to the invocation handler's invoke method in the same manner as interface method invocations are encoded and dispatched, as described above. The declaring class of the Method object passed to invoke will be java.lang.Object. Other public methods of a proxy instance inherited from java.lang.Object are not overridden by a proxy class, so invocations of those methods behave like they do for instances of java.lang.Object.<br />
Methods Duplicated in Multiple Proxy Interfaces<br />
<br />
When two or more interfaces of a proxy class contain a method with the same name and parameter signature, the order of the proxy class's interfaces becomes significant. When such a duplicate method is invoked on a proxy instance, the Method object passed to the invocation handler will not necessarily be the one whose declaring class is assignable from the reference type of the interface that the proxy's method was invoked through. This limitation exists because the corresponding method implementation in the generated proxy class cannot determine which interface it was invoked through. Therefore, when a duplicate method is invoked on a proxy instance, the Method object for the method in the foremost interface that contains the method (either directly or inherited through a superinterface) in the proxy class's list of interfaces is passed to the invocation handler's invoke method, regardless of the reference type through which the method invocation occurred.<br />
<br />
If a proxy interface contains a method with the same name and parameter signature as the hashCode, equals, or toString methods of java.lang.Object, when such a method is invoked on a proxy instance, the Method object passed to the invocation handler will have java.lang.Object as its declaring class. In other words, the public, non-final methods of java.lang.Object logically precede all of the proxy interfaces for the determination of which Method object to pass to the invocation handler.<br />
<br />
Note also that when a duplicate method is dispatched to an invocation handler, the invoke method may only throw checked exception types that are assignable to one of the exception types in the throws clause of the method in all of the proxy interfaces that it can be invoked through. If the invoke method throws a checked exception that is not assignable to any of the exception types declared by the method in one of the proxy interfaces that it can be invoked through, then an unchecked UndeclaredThrowableException will be thrown by the invocation on the proxy instance. This restriction means that not all of the exception types returned by invoking getExceptionTypes on the Method object passed to the invoke method can necessarily be thrown successfully by the invoke method.<br />
<br />
Since:<br />
1.3<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-79703216795420475212012-06-02T07:42:00.000+05:302012-07-17T23:17:45.401+05:30GIST NOTES 15 - Java JDBC<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 15 - Java JDBC</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
JDBC - Java DB Connectivity<br />
ODBC - Open DB Connectivity<br />
<br />
A Relational Database Overview<br />
<br />
A database is a means of storing information in such a way that information can be retrieved from it. In simplest terms, a relational database is one that presents information in tables with rows and columns. A table is referred to as a relation in the sense that it is a collection of objects of the same type (rows). Data in a table can be related according to common keys or concepts, and the ability to retrieve related data from a table is the basis for the term relational database. A Database Management System (DBMS) handles the way data is stored, maintained, and retrieved. In the case of a relational database, a Relational Database Management System (RDBMS) performs these tasks. DBMS as used in this book is a general term that includes RDBMS.<br />
<br />
Integrity Rules<br />
<br />
Relational tables follow certain integrity rules to ensure that the data they contain stay accurate and are always accessible. First, the rows in a relational table should all be distinct. If there are duplicate rows, there can be problems resolving which of two possible selections is the correct one. For most DBMSs, the user can specify that duplicate rows are not allowed, and if that is done, the DBMS will prevent the addition of any rows that duplicate an existing row.<br />
<br />
A second integrity rule of the traditional relational model is that column values must not be repeating groups or arrays. A third aspect of data integrity involves the concept of a null value. A database takes care of situations where data may not be available by using a null value to indicate that a value is missing. It does not equate to a blank or zero. A blank is considered equal to another blank, a zero is equal to another zero, but two null values are not considered equal.<br />
<br />
When each row in a table is different, it is possible to use one or more columns to identify a particular row. This unique column or group of columns is called a primary key. Any column that is part of a primary key cannot be null; if it were, the primary key containing it would no longer be a complete identifier. This rule is referred to as entity integrity.<br />
<br />
>There are three different kinds of statements:<br />
<br />
Statement: Used to implement simple SQL statements with no parameters.<br />
PreparedStatement: (Extends Statement.) Used for precompiling SQL statements that might contain input parameters. See Using Prepared Statements for more information.<br />
CallableStatement: (Extends PreparedStatement.) Used to execute stored procedures that may contain both input and output parameters. See Stored Procedures for more information.<br />
<br />
>Executing Queries<br />
<br />
To execute a query, call an execute method from Statement such as the following:<br />
<br />
execute: Returns true if the first object that the query returns is a ResultSet object. Use this method if the query could return one or more ResultSet objects. Retrieve the ResultSet objects returned from the query by repeatedly calling Statement.getResultSet.<br />
executeQuery: Returns one ResultSet object.<br />
executeUpdate: Returns an integer representing the number of rows affected by the SQL statement. Use this method if you are using INSERT, DELETE, or UPDATE SQL statements.<br />
For example, CoffeeTables.viewTable executed a Statement object with the following code:<br />
<br />
ResultSet rs = stmt.executeQuery(query);<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> <br />
>Using the DriverManager Class<br />
<br />
Connecting to your DBMS with the DriverManager class involves calling the method DriverManager.getConnection. The following method, JDBCTutorialUtilities.getConnection, establishes a database connection:<br />
<br />
public Connection getConnection() throws SQLException {<br />
Connection conn = null;<br />
Properties connectionProps = new Properties();<br />
connectionProps.put("user", this.userName);<br />
connectionProps.put("password", this.password);<br />
<br />
if (this.dbms.equals("mysql")) {<br />
conn = DriverManager.<br />
getConnection("jdbc:" + this.dbms + "://" + this.serverName +<br />
":" + this.portNumber + "/", connectionProps);<br />
} else if (this.dbms.equals("derby")) {<br />
conn = DriverManager.<br />
getConnection("jdbc:" + this.dbms + ":" + this.dbName + ";create=true", connectionProps);<br />
}<br />
System.out.println("Connected to database");<br />
return conn;<br />
}<br />
<br />
The method DriverManager.getConnection establishes a database connection. This method requires a database URL, which varies depending on your DBMS. The following are some examples of database URLs:<br />
<br />
MySQL: jdbc:mysql://localhost:3306/, where localhost is the name of the server hosting your database, and 3306 is the port number<br />
<br />
Java DB: jdbc:derby:testdb;create=true, where testdb is the name of the database to connect to, and create=true instructs the DBMS to create the database.<br />
<br />
Note: This URL establishes a database connection with the Java DB Embedded Driver. Java DB also includes a Network Client Driver, which uses a different URL.<br />
<br />
This method specifies the user name and password required to access the DBMS with a Properties object.<br />
<br />
Note:<br />
<br />
Typically, in the database URL, you also specify the name of an existing database to which you want to connect. For example, the URL jdbc:mysql://localhost:3306/mysql represents the database URL for the MySQL database named mysql. The samples in this tutorial use a URL that does not specify a specific database because the samples create a new database.<br />
<br />
In previous versions of JDBC, to obtain a connection, you first had to initialize your JDBC driver by calling the method Class.forName. This methods required an object of type java.sql.Driver. Each JDBC driver contains one or more classes that implements the interface java.sql.Driver. The drivers for Java DB are org.apache.derby.jdbc.EmbeddedDriver and org.apache.derby.jdbc.ClientDriver, and the one for MySQL Connector/J is com.mysql.jdbc.Driver. See the documentation of your DBMS driver to obtain the name of the class that implements the interface java.sql.Driver.<br />
<br />
Any JDBC 4.0 drivers that are found in your class path are automatically loaded. (However, you must manually load any drivers prior to JDBC 4.0 with the method Class.forName.)<br />
<br />
The method returns a Connection object, which represents a connection with the DBMS or a specific database. Query the database through this object.<br />
<br />
Transaction Processing<br />
----------------------<br />
>Use connection.setAutoCommit(false), connection.commit() and connection.rollback() methods to do transaction processing<br />
<br />
>The method begins by creating a Savepoint with the following statement:<br />
<br />
Savepoint save1 = con.setSavepoint();<br />
The method checks if the new price is greater than the maximumPrice value. If so, the method rolls back the transaction with the following statement:<br />
<br />
con.rollback(save1);<br />
Consequently, when the method commits the transaction by calling the Connection.commit method, it will not commit any rows whose associated Savepoint has been rolled back; it will commit all the other updated rows.<br />
<br />
---<br />
<br />
>clob: character large object<br />
>blob: binary large object<br />
>nclob: national character large object<br />
<br />
>RowSet/JdbcSet/CachedSet/.... these sets allow to scroll up and down, update data, join tables, offline/online operations to DB, caching and such facilities are provided on top of ResultSet; RowSet also provides event mechanism with listener model to listen on data changes on a particular row<br />
<br />
>>Stemps involved in JDBC connection<br />
1.Establishing a connection.<br />
2.Create a statement.<br />
3.Execute the query.<br />
4.Process the ResultSet object.<br />
5.Close the connection.<br />
<div>
<br /></div>
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-49457376900855349432012-06-01T07:40:00.000+05:302012-07-17T23:17:45.337+05:30GIST NOTES 14 - Java Garbage Collection<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 14 - Java Garbage Collection</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
<a href="http://www.oracle.com/technetwork/java/javase/tech/memorymanagement-whitepaper-1-150020.pdf">http://www.oracle.com/technetwork/java/javase/tech/memorymanagement-whitepaper-1-150020.pdf</a><br />
<br />
>a technique new in the J2SE 5.0 release that combines (1) automatic selection of garbage<br />
collector, heap sizes, and HotSpot JVM (client or server) based on the platform and operating system on which the application is running, and (2) dynamic garbage collection tuning based on user-specified desired behavior. This technique is referred to as ergonomics.<br />
<br />
<b>Design Choices</b><br />
<br />
A number of choices must be made when designing or selecting a garbage collection algorithm:<br />
<br />
<b>• Serial versus Parallel</b><br />
<br />
With serial collection, only one thing happens at a time. For example, even when multiple CPUs are<br />
available, only one is utilized to perform the collection. When parallel collection is used, the task of<br />
garbage collection is split into parts and those subparts are executed simultaneously, on different<br />
CPUs. The simultaneous operation enables the collection to be done more quickly, at the expense of<br />
some additional complexity and potential fragmentation.<br />
<br />
<b>• Concurrent versus Stop-the-world</b><br />
<br />
When stop-the-world garbage collection is performed, execution of the application is completely<br />
suspended during the collection. Alternatively, one or more garbage collection tasks can be executed<br />
concurrently, that is, simultaneously, with the application. Typically, a concurrent garbage collector<br />
does most of its work concurrently, but may also occasionally have to do a few short stop-the-world<br />
pauses. Stop-the-world garbage collection is simpler than concurrent collection, since the heap is<br />
frozen and objects are not changing during the collection. Its disadvantage is that it may be<br />
undesirable for some applications to be paused. Correspondingly, the pause times are shorter when<br />
garbage collection is done concurrently, but the collector must take extra care, as it is operating over<br />
objects that might be updated at the same time by the application. This adds some overhead to<br />
concurrent collectors that affects performance and requires a larger heap size.<br />
<br />
<b>• Compacting versus Non-compacting versus Copying</b><br />
<b><br /></b><br />
After a garbage collector has determined which objects in memory are live and which are garbage, it<br />
can compact the memory, moving all the live objects together and completely reclaiming the<br />
remaining memory. After compaction, it is easy and fast to allocate a new object at the first free<br />
location. A simple pointer can be utilized to keep track of the next location available for object<br />
allocation. In contrast with a compacting collector, a non-compacting collector releases the space<br />
utilized by garbage objects in-place, i.e., it does not move all live objects to create a large reclaimed<br />
region in the same way a compacting collector does. The benefit is faster completion of garbage<br />
collection, but the drawback is potential fragmentation. In general, it is more expensive to allocate<br />
from a heap with in-place deallocation than from a compacted heap. It may be necessary to search the<br />
heap for a contiguous area of memory sufficiently large to accommodate the new object. A third<br />
alternative is a copying collector, which copies (or evacuates) live objects to a different memory area.<br />
The benefit is that the source area can then be considered empty and available for fast and easy<br />
subsequent allocations, but the drawback is the additional time required for copying and the extra<br />
space that may be required.<br />
<br />
<b>>Performance Metrics</b><br />
Several metrics are utilized to evaluate garbage collector performance, including:<br />
<br />
• <b>Throughput</b>—the percentage of total time not spent in garbage collection, considered over long<br />
periods of time.<br />
<br />
• <b>Garbage collection overhead</b>—the inverse of throughput, that is, the percentage of total time spent in<br />
garbage collection.<br />
<br />
• <b>Pause time</b>—the length of time during which application execution is stopped while garbage<br />
collection is occurring.<br />
<br />
• <b>Frequency of collection</b>—how often collection occurs, relative to application execution.<br />
<br />
• <b>Footprint</b>—a measure of size, such as heap size.<br />
<br />
• <b>Promptness</b>—the time between when an object becomes garbage and when the memory becomes<br />
available.<br />
<br />
<b>HotSpot Generations</b><br />
<br />
Memory in the Java HotSpot virtual machine is organized into three generations: a young generation, an old<br />
generation, and a permanent generation. Most objects are initially allocated in the young generation. The old<br />
generation contains objects that have survived some number of young generation collections, as well as some<br />
large objects that may be allocated directly in the old generation. The permanent generation holds objects that the JVM finds convenient to have the garbage collector manage, such as objects describing classes and methods, as well as the classes and methods themselves.<br />
<br />
The young generation consists of an area called Eden plus two smaller survivor spaces, as shown in Figure 2. Most objects are initially allocated in Eden. (As mentioned, a few large objects may be allocated directly in the old generation.) The survivor spaces hold objects that have survived at least one young generation collection and have thus been given additional chances to die before being considered “old enough” to be promoted to the old generation. At any given time, one of the survivor spaces (labeled From in the figure) holds such objects, while the other is empty and remains unused until the next collection.<br />
<br />
<b>>young generation collection is known as minor collection</b><br />
<b><br /></b><br />
>young generation fills up - minor collection(collection on young generation alone) is triggered<br />
>old generation fills up - major collection(collection on all generations) is triggered<br />
>old generation collection algorithm is used on both old and permanent generations (compaction occurs separately for these two generations)<br />
>young generation collection algorithm is used always on young generation except when old generation doesn't have space to accommodate new promoted objects from young gen. In this case, old generation algorithm(not CMS) is used on the entire heap<br />
>CMS - Concurrent Mark Sweep Collector<br />
>For multithreaded applications, allocation operations need to be multithread-safe. If global locks were used to ensure this, then allocation into a generation would become a bottleneck and degrade performance. Instead, the HotSpot JVM has adopted a technique called Thread-Local Allocation Buffers (TLABs). This improves multithreaded allocation throughput by giving each thread its own buffer (i.e., a small portion of the<br />
generation) from which to allocate. Since only one thread can be allocating into each TLAB, allocation can take place quickly by utilizing the bump-the-pointer technique, without requiring any locking. Only infrequently, when a thread fills up its TLAB and needs to get a new one, must synchronization be utilized. Several techniques to minimize space wastage due to the use of TLABs are employed. For example, TLABs are sized by the allocator to waste less than 1% of Eden, on average. The combination of the use of TLABs and linear allocations using the bump-the-pointer technique enables each allocation to be efficient, only requiring around 10 native instructions.<br />
<br />
>tenured - promoted to old gen<br />
<br />
>Parallel Collector<br />
<br />
These days, many Java applications run on machines with a lot of physical memory and multiple CPUs. The<br />
parallel collector, also known as the throughput collector, was developed in order to take advantage of available CPUs rather than leaving most of them idle while only one does garbage collection work.<br />
<br />
>Serial collectors always use stop-the-world method<br />
<br />
>Parallel means gc runs on multiple CPUs<br />
<br />
>Concurrent means GC runs along with user application<br />
<br />
>Parallel collectors need not be concurrent, they can settle for stop-the-world method<br />
<br />
>Young Generation Collection Using the Parallel Collector<br />
<br />
The parallel collector uses a parallel version of the young generation collection algorithm utilized by the<br />
serial collector. It is still a stop-the-world and copying collector, but performing the young generation collection in parallel, using many CPUs, decreases garbage collection overhead and hence increases<br />
application throughput. The only difference between them is pause time is lesser for parallel collector<br />
>young generation collector is called copying collector because, live objects are moved from 'Eden' to 'Survivor' and 'From Survivor' to 'To Survivor' spaces<br />
<br />
>Old Generation Collection Using the Parallel Collector<br />
<br />
Old generation garbage collection for the parallel collector is done using the same serial mark-sweepcompact collection algorithm as the serial collector.<br />
<br />
<b>When to Use the Parallel Collector</b><br />
<b><br /></b><br />
Applications that can benefit from the parallel collector are those that run on machines with more than<br />
one CPU and do not have pause time constraints, since infrequent, but potentially long, old generation<br />
collections will still occur. Examples of applications for which the parallel collector is often appropriate<br />
include those that do batch processing, billing, payroll, scientific computing, and so on.<br />
<br />
You may want to consider choosing the parallel compacting collector (described next) over the parallel<br />
collector, since the former performs parallel collections of all generations, not just the young<br />
generation.<br />
<br />
<b>>Parallel Collector Selection</b><br />
<br />
In the J2SE 5.0 release, the parallel collector is automatically chosen as the default garbage collector on<br />
server-class machines (defined in Section 5). On other machines, the parallel collector can be explicitly<br />
requested by using the -XX:+UseParallelGC command line option.<br />
<br />
>Parallel Compacting Collector Selection<br />
<br />
If you want the parallel compacting collector to be used, you must select it by specifying the<br />
command line option -XX:+UseParallelOldGC.<br />
<br />
>Concurrent Mark-Sweep (CMS) Collector<br />
<br />
For many applications, end-to-end throughput is not as important as fast response time. Young generation<br />
collections do not typically cause long pauses. However, old generation collections, though infrequent, can<br />
impose long pauses, especially when large heaps are involved. To address this issue, the HotSpot JVM includes a collector called the concurrent mark-sweep (CMS) collector, also known as the low-latency collector.<br />
<br />
>Serial-Copying to Parallel to Parallel-Compacting to Concurrent-Mark-Sweep; that is all about the flavors of gc collectors<br />
<br />
>If your application or environmental characteristics are such that a different collector than the default is<br />
warranted, explicitly request that collector via one of the following command line options:<br />
–XX:+UseSerialGC<br />
–XX:+UseParallelGC<br />
–XX:+UseParallelOldGC<br />
–XX:+UseConcMarkSweepGC<br />
<br />
>The size of the heap will oscillate as the garbage collector tries to satisfy competing goals, even if the<br />
application has reached a steady state. The pressure to achieve a throughput goal (which may require a larger heap) competes with the goals for a maximum pause time and a minimum footprint (which both may require a smaller heap).<br />
<br />
<b>>Refer whitepaper for CMS</b><br />
<br />
>7 Tools to Evaluate Garbage Collection Performance<br />
<br />
Various diagnostic and monitoring tools can be utilized to evaluate garbage collection performance. This section provides a brief overview of some of them. For more information, see the “Tools and Troubleshooting” links in Section 9.<br />
<br />
–XX:+PrintGCDetails Command Line Option<br />
<br />
One of the easiest ways to get initial information about garbage collections is to specify the command line<br />
option –XX:+PrintGCDetails. For every collection, this results in the output of information such as the<br />
size of live objects before and after garbage collection for the various generations, the total available space for each generation, and the length of time the collection took.<br />
<br />
–XX:+PrintGCTimeStamps Command Line Option<br />
<br />
This outputs a timestamp at the start of each collection, in addition to the information that is output if the<br />
command line option –XX:+PrintGCDetails is used. The timestamps can help you correlate garbage<br />
collection logs with other logged events.<br />
<br />
jmap<br />
<br />
jmap is a command line utility included in the Solaris™ Operating Environment and Linux (but not Windows)<br />
releases of the Java Development Kit (JDK™). It prints memory–related statistics for a running JVM or core file. If it is used without any command line options, then it prints the list of shared objects loaded, similar to what the Solaris pmap utility outputs. For more specific information, the –heap, –histo, or –permstat options can be used.<br />
<br />
The –heap option is used to obtain information that includes the name of the garbage collector,<br />
algorithm–specific details (such as the number of threads being used for parallel garbage collection), heap<br />
configuration information, and a heap usage summary<br />
<br />
The –histo option can be used to obtain a class–wise histogram of the heap. For each class, it prints the number of instances in the heap, the total amount of memory consumed by those objects in bytes, and the fully qualified class name. The histogram is useful when trying to understand how the heap is used.<br />
Configuring the size of the permanent generation can be important for applications that dynamically generate<br />
and load a large number of classes (Java Server Pages™ and web containers, for example). If an application loads “too many” classes, then an OutOfMemoryError is thrown.<br />
<br />
The –permstat option to the jmap command can be used to get statistics for the objects in the permanent generation.<br />
<br />
jstat<br />
<br />
The jstat utility uses the built–in instrumentation in the HotSpot JVM to provide information on performance<br />
and resource consumption of running applications. The tool can be used when diagnosing performance issues, and in particular issues related to heap sizing and garbage collection. Some of its many options can print statistics regarding garbage collection behavior and the capacities and usage of the various generations.<br />
<br />
17 Tools to Evaluate Garbage Collection Performance Sun Microsystems, Inc.<br />
<br />
HPROF: Heap Profiler<br />
<br />
HPROF is a simple profiler agent shipped with JDK 5.0. It is a dynamically–linked library that interfaces to the JVM using the Java Virtual Machine Tools Interface (JVM TI). It writes out profiling information either to a file or to a socket in ASCII or binary format. This information can be further processed by a profiler front–end tool.<br />
<br />
HPROF is capable of presenting CPU usage, heap allocation statistics, and monitor contention profiles. In<br />
addition, it can output complete heap dumps and report the states of all the monitors and threads in the Java<br />
virtual machine. HPROF is useful when analyzing performance, lock contention, memory leaks, and other issues.<br />
<br />
See Section 9 for a link to HPROF documentation.<br />
<br />
HAT: Heap Analysis Tool<br />
<br />
The Heap Analysis Tool (HAT) helps debug unintentional object retention. This term is used to describe an object that is no longer needed but is kept alive due to references through some path from a live object. HAT provides a convenient means to browse the object topology in a heap snapshot that is generated using HPROF. The tool allows a number of queries, including “show me all reference paths from the rootset to this object.” See Section 9 for a link to HAT documentation.<br />
<br />
Java 1.7 G1 Garbage Collector<br />
-----------------------------<br />
In Java 1.7 might have a new garbage collection strategy by default. It is called G1, which is short for Garbage First. It has been experimentally launched in the Java 1.6 update 14 to replace the regular Concurrent Mark and Sweep Garbage Collectors with increased performance.<br />
<br />
G1 is considered as "server centric" with following attributes.<br />
<br />
G1 uses parallelism which are mostly used in hardware today.The main advantage of G1 is designed in such a way to make use of all available CPU's and utilize the processing power of all CPU's and increase the performance and speed in Garbage Collection.<br />
<br />
Concurrency feature of G1 allows to run Java threads to minimize the heap operations at stop pauses.<br />
Next feature which plays a key role in increasing the Garbage Collection is treating the young objects(newly created) and the old objects(which lived for some time) differently.G1 mainly focuses on young objects as they can be reclaimable when traversing the old objects.<br />
<br />
Heap compaction is done to eliminate fragmentation problems.<br />
<br />
G1 can be more predictable when compared to CMS.<br />
<br />
Features of G1 Garbage Collector<br />
<br />
A single contiguous heap which is split into same-sized regions. No separation between younger and older regions.<br />
<br />
G1 uses evacuation pauses.Evacuation pauses are done in parallel by using all the available processors.<br />
<br />
G1 uses a pause prediction model to meet user-defined pause time targets<br />
<br />
Like CMS,G1 also periodically performs a concurrent marking phase.<br />
<br />
Unlike CMS, G1 does not perform a concurrent sweeping phase.<br />
<div>
<br /></div>
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-8001542986078399232012-05-31T07:37:00.000+05:302012-07-17T23:17:45.407+05:30GIST NOTES 13 - Design Patterns<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 13 - Design Patterns</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
OO Principles<br />
-------------<br />
-separate or encapsulate what changes frequently<br />
-program to type/interface not the implementation<br />
-Favor composition over inheritance<br />
-Strive for loosely coupled designs between objects that interact<br />
-Classes should be open for extension, but closed for modification.<br />
-Dependency Inversion Principle:Depend upon abstractions. Do not depend upon concrete classes.<br />
[[In object-oriented programming, the dependency inversion principle refers to a specific form of decoupling where conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are inverted (i.e. reversed) for the purpose of rendering high-level modules independent of the low-level module implementation details. The principle states:<br />
<br />
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.<br />
B. Abstractions should not depend upon details. Details should depend upon abstractions.<br />
]]<br />
-Principle of Least Knowledge: talk only to your immediate friends.<br />
-The Hollywood Principle: Don’t call us, we’ll call you.<br />
-Single Responsibility Principle: A class should have only one reason to change.<br />
<br />
Strategy Pattern --> (Pluggable Discovery Modules)<br />
<br />
defines a family of algorithms,<br />
encapsulates each one, and makes them<br />
interchangeable. Strategy lets the algorithm<br />
vary independently from clients that use it.<br />
<br />
The Observer Pattern --> (Swing Event Listeners)<br />
<br />
defines a one-to-many<br />
dependency between objects so that when one<br />
object changes state, all of its dependents are<br />
notified and updated automatically.<br />
<br />
-java.util.Observable is a class; Observer is an interface<br />
If you look at the Observable API, the setChanged() method is protected. So what? Well,<br />
this means you can’t call setChanged() unless you’ve subclassed Observable. This means<br />
you can’t even create an instance of the Observable class and compose it with your own<br />
objects, you have to subclass. The design violates a second design principle here…favor<br />
composition over inheritance.<br />
<br />
ß Swing makes heavy use of the<br />
Observer Pattern, as do many<br />
GUI frameworks.<br />
ß You’ll also find the pattern in<br />
many other places, including<br />
JavaBeans and RMI.<br />
<br />
Many of the patterns give us<br />
time tested designs that protect your<br />
code from being modified by supplying<br />
a means of extension. In this chapter<br />
you’ll see a good example of using the<br />
Decorator pattern to follow the Open-<br />
Closed principle.<br />
<br />
The Decorator Pattern --> (Java IO Package)<br />
<br />
attaches additional responsibilities to an object dynamically.<br />
Decorators provide a flexible alternative to subclassing for extending functionality.<br />
<br />
Decorator pattern makes the addon components of a main component as same type as main component and also these addons<br />
can wrap the main component or another addon since they all extend from same supertype. Such wrapper addons<br />
are called decorator classes. So decorators make adding addons to main component in any combination, easier.<br />
<br />
Main classes and abstract decorator extend from supertype. Addon components extend from decorator.<br />
<br />
Decorators have the same supertype as the objects they decorate.<br />
<br />
But now that you know the Decorator Pattern, the I/O classes should make more sense<br />
since the java.io package is largely based on Decorator.<br />
<br />
FileInputStream and FilterInputStream extend from InputStrem.<br />
<br />
FileInputStream is the subject which is decorated. FilterInputStream is the<br />
abstract Decorator class from which concrete decorators like BufferedInputStream<br />
and LineNumberInputStream extend.<br />
<br />
But Java I/O also points out one of the downsides of the Decorator Pattern:<br />
designs using this pattern often result in a large number of small classes<br />
that can be overwhelming to a developer trying to use the Decorator-based<br />
API.<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<br />
Factory Pattern --> (Pluggable PortModules in a Switch EMS)<br />
<br />
Simple Factory is not a Pattern. It is a programming idiom.<br />
<br />
The Factory Method Pattern --><br />
<br />
defines an interface for creating an object, but lets subclasses decide which<br />
class to instantiate. Factory Method lets a class defer<br />
instantiation to subclasses.<br />
<br />
The Abstract Factory Pattern --><br />
<br />
provides an interface for creating families of related or dependent objects<br />
without specifying their concrete classes.<br />
<br />
Factory Method - creates objects through inheritance<br />
Abstract Factory - creates objects through object composition<br />
<br />
The Singleton Pattern --> (Discovery Engine/Console object EMS/NMS)<br />
<br />
ensures a class has only one instance, and provides a global point of access to it.<br />
<br />
Double-checked locking doesn’t work in Java 1.4 or earlier!<br />
<br />
Unfortunately, in Java version 1.4 and earlier, many<br />
JVMs contain implementations of the volatile keyword<br />
that allow improper synchronization for double-checked<br />
locking. If you must use a JVM other than Java 5,<br />
consider other methods of implementing your Singleton.<br />
<br />
For each solution, describe its applicability to the problem of fixing the Chocolate<br />
Boiler code:<br />
Sharpen your pencil<br />
Synchronize the getInstance() method:<br />
Use eager instantiation:<br />
Double-checked locking:<br />
<br />
Prior to Java 1.2, a bug in the garbage collector allowed Singletons<br />
to be prematurely collected if there was no global reference to them. In other<br />
words, you could create a Singleton and if the only reference to the Singleton<br />
was in the Singleton itself, it would be collected and destroyed by the garbage<br />
collector.<br />
<br />
One problem with subclassing<br />
Singleton is that the constructor is<br />
private. You can’t extend a class with<br />
a private constructor.<br />
<br />
intent of the pattern: to<br />
ensure only one instance of a class<br />
exists and to provide global access. A<br />
global variable can provide the latter,<br />
but not the former.<br />
<br />
Be careful if you are using<br />
multiple class loaders; this<br />
could defeat the Singleton<br />
implementation and result in<br />
multiple instances.<br />
<br />
If you are using a JVM earlier<br />
than 1.2, you’ll need to create a<br />
registry of Singletons to defeat<br />
the garbage collector.<br />
<br />
<1.2 garbage collector issue<br />
<1.4 volatile allowed improper synchronization<br />
<br />
public class Singleton {<br />
*private* *volatile* static Singleton uniqueInstance;<br />
*private* Singleton() {}<br />
public static Singleton getInstance() {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if (uniqueInstance == null**) {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>synchronized (Singleton.class**) {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if (uniqueInstance == null**) {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>uniqueInstance = new Singleton();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>return uniqueInstance;<br />
}<br />
<br />
}<br />
<br />
Need for volatile - since we are moving from method level sync to block level sync, the threads would keep separate copy of static variables in their stack instead of referring from heap. To avoid this, we make the variable involved as volatile. Or use a local variable inside the method to read/write uniqueInstance variable<br />
<br />
Command Pattern --><br />
<br />
The Command Pattern encapsulates a request as an<br />
object, thereby letting you parameterize other objects<br />
with different requests, queue or log requests, and support<br />
undoable operations.<br />
<br />
The Meta Command Pattern allows you to create<br />
macros of commands so that you can execute multiple commands<br />
at once.<br />
<br />
Adapter Pattern --><br />
<br />
The Adapter Pattern converts the interface of a class<br />
into another interface the clients expect. Adapter lets<br />
classes work together that couldn’t otherwise because of<br />
incompatible interfaces.<br />
<br />
There are actually two kinds of adapters: object adapters and class adapters.<br />
<br />
This chapter has covered object adapters and the class diagram on the previous page is a<br />
diagram of an object adapter.<br />
So what’s a class adapter and why haven’t we told you about it? Because you need<br />
multiple inheritance to implement it, which isn’t possible in Java. But, that doesn’t<br />
mean you might not encounter a need for class adapters down the road when using<br />
your favorite multiple inheritance language!<br />
<br />
Object adapters and class adapters use two different means of<br />
adapting the adaptee (composition versus inheritance).<br />
<br />
Facade Pattern --><br />
<br />
We’re going to look at a pattern now that alters an interface, but for a<br />
different reason: to simplify the interface. It’s aptly named the Facade<br />
Pattern because this pattern hides all the complexity of one or more<br />
classes behind a clean, well-lit facade.<br />
<br />
Decorator -<br />
Doesn’t alter the interface, but<br />
adds responsibility<br />
<br />
Adapter -<br />
Converts one interface to<br />
another<br />
<br />
Facade -<br />
Makes an interface simpler<br />
<br />
with the Facade Pattern you can take a complex<br />
subsystem and make it easier to use by implementing a Facade class that<br />
provides one but more-reasonable interface.<br />
<br />
difference between the Adapter Pattern and the<br />
Facade Pattern is that the adapter wraps<br />
one class and the facade may represent<br />
many classes?<br />
A: No! Remember, the Adapter Pattern<br />
changes the interface of one or more<br />
classes into one interface that a client is<br />
expecting. While most textbook examples<br />
show the adapter adapting one class, you<br />
may need to adapt many classes to provide<br />
the interface a client is coded to. Likewise,<br />
a Facade may provide a simplified interface<br />
to a single class with a very complex<br />
interface.<br />
The difference between the two is not in<br />
terms of how many classes they “wrap,” it<br />
is in their intent. The intent of the Adapter<br />
Pattern is to alter an interface so that it<br />
matches one a client is expecting. The<br />
intent of the Facade Pattern is to provide a<br />
simplified interface to a subsystem.<br />
<br />
A facade not only simplifies an interface, it<br />
decouples a client from a subsystem of components.<br />
<br />
The Facade Pattern provides a unified interface to a<br />
set of interfaces in a subsytem. Facade defines a higherlevel<br />
interface that makes the subsystem easier to use.<br />
<br />
Principle of Least Knowledge - Law of Demeter<br />
talk only to your immediate friends.<br />
<br />
Are there any disadvantages<br />
to applying the Principle of Least<br />
Knowledge?<br />
A: Yes; while the principle reduces<br />
the dependencies between objects and<br />
studies have shown this reduces software<br />
maintenance, it is also the case that<br />
applying this principle results in more<br />
“wrapper” classes being written to handle<br />
method calls to other components. This<br />
can result in increased complexity and<br />
development time as well as decreased<br />
runtime performance.<br />
<br />
Adapter Pattern - interface is dictated by Clients<br />
Facade Pattern - no one dictate the interface; it is just a simplification of a complex subsystem<br />
<br />
Template Method Pattern(Hollywood Principle) --> (Swing paint() and Arrays/Collections.sort())<br />
<br />
The Template Method defines the steps of an algorithm and allows<br />
subclasses to provide the implementation for one or more steps.<br />
<br />
The Template Method Pattern defines the skeleton<br />
of an algorithm in a method, deferring some steps to<br />
subclasses. Template Method lets subclasses redefine<br />
certain steps of an algorithm without changing the<br />
algorithm’s structure.<br />
<br />
Use abstract methods when your subclass MUST provide an implementation<br />
of the method or step in the algorithm. Use hooks when that part of the algorithm<br />
is optional. With hooks, a subclass may choose to implement that hook, but it doesn’t<br />
have to.<br />
<br />
Another use is to give the subclass a chance to react to some step in the<br />
template method that is about to happen, or just happened.<br />
<br />
abstract method - forces the subclasses to implement a step in the algorithm<br />
hooks - provide optional steps for subclasses<br />
<br />
The Hollywood Principle: Don’t call us, we’ll call you.<br />
<br />
The Hollywood principle gives us a way to prevent<br />
“dependency rot.” Dependency rot happens when you have<br />
high-level components depending on low-level components<br />
depending on high-level components depending on sideways<br />
components depending on low-level components, and so on.<br />
When rot sets in, no one can easily understand the way a<br />
system is designed.<br />
<br />
the high-level components give the low-level<br />
components a “don’t call us, we’ll call you” treatment.<br />
<br />
when we design with the Template Method Pattern, we’re telling subclasses, “don’t call us, we’ll call<br />
you.”<br />
<br />
Template Method<br />
<br />
Subclasses decide how to implement steps in an algorithm<br />
<br />
Strategy<br />
<br />
*Encapsulate* interchangeable behaviors and use *delegation* to decide which behavior to use<br />
<br />
Factory Method (about creation of objects in the subclasses)<br />
<br />
Subclasses decide which concrete classes to create<br />
<br />
you’re going to have to implement this compareTo()<br />
method; by doing that you’ll give the Arrays class<br />
what it needs to complete the algorithm and sort - Arrays util class sort()<br />
method uses Template patttern but without inheritance.<br />
<br />
The designers of the Arrays sort() method had a few constraints. In general, you can’t<br />
subclass a Java array and they wanted the sort to be used on all arrays (and each array<br />
is a different class). So they defined a static method and deferred the comparison part of the algorithm to the items being sorted. So, while it’s not a textbook template<br />
method, this implementation is still in the spirit of the Template Method Pattern.<br />
<br />
But remember, in Strategy pattern, the class that you compose<br />
with implements the entire algorithm. The algorithm that Arrays implements for sort<br />
is incomplete; it needs a class to fill in the missing compareTo() method. So, in that<br />
way, it’s more like Template Method.<br />
<br />
Are there other examples of template methods in the Java API?<br />
A: Yes, you’ll find them in a few places. For example, java.io has a read()<br />
method in InputStream that subclasses must implement and is used by the template<br />
method read(byte b[], int off, int len).<br />
<br />
If you haven’t encountered JFrame, it’s the most basic Swing container and inherits<br />
a paint() method. By default, paint() does nothing because it’s a hook! By overriding<br />
paint(), you can insert yourself into JFrame’s algorithm for displaying its area of the<br />
screen and have your own graphic output incorporated into the JFrame.<br />
<br />
Hook method is a missing step in the template method pattern algorithm which is deferred to clients to be implemented later if they want.<br />
<br />
We’re extending JFrame, which contains a method update() that controls the<br />
algorithm for updating the screen. We can hook into that algorithm by<br />
overriding the paint() hook method.<br />
<br />
The init() hook allows the applet to do whatever it wants to initialize the applet the first time.<br />
<br />
repaint() is a concrete method in the Applet class that lets upper-level components know<br />
the applet needs to be redrawn.<br />
<br />
And many other methods in Applet class are hooks.<br />
<br />
To prevent subclasses from changing the algorithm in the<br />
template method, declare the template method as final.<br />
<br />
The Strategy and Template Method Patterns both<br />
encapsulate algorithms, one by inheritance and one by composition.<br />
<br />
The Factory Method is a specialization of Template Method.<br />
<br />
Iterator Pattern ===> (Java Collections)<br />
<br />
The Iterator Pattern provides a way to access the elements of an aggregate object<br />
sequentially without exposing its underlying representation.<br />
<br />
Iterator Pattern places the task of traversal on the iterator<br />
object, not on the aggregate, which simplifies the<br />
aggregate interface and implementation, and places<br />
the responsibility where it should be.<br />
<br />
Q: I’ve heard about “internal” iterators and “external” iterators. What<br />
are they? Which kind did we implement in the example?<br />
A: We implemented an external iterator, which means that the client controls the<br />
iteration by calling next() to get the next element. An internal iterator is controlled<br />
by the iterator itself. In that case, because it’s the iterator that’s stepping through the<br />
elements, you have to tell the iterator what to do with those elements as it goes through<br />
them. That means you need a way to pass an operation to an iterator. Internal iterators<br />
are less flexible than external iterators because the client doesn’t have control of<br />
the iteration.<br />
<br />
Java’s Collection Framework ListIterator can go backwards as well as forwards<br />
It is supported by any Collection that implements the List interface.<br />
<br />
A class should have only one reason to change.<br />
<br />
Every responsibility of a class is an area of potential change. More than one<br />
responsibility means more than one area of change.<br />
<br />
We say that a module or class has high cohesion when it is designed around a set of<br />
related functions, and we say it has low cohesion when it is designed around a<br />
set of unrelated functions.<br />
<br />
Composite Pattern ===><br />
<br />
The Composite Pattern allows you to compose objects into tree structures to<br />
represent part-whole hierarchies. Composite lets clients treat individual objects and<br />
compositions of objects uniformly.<br />
<br />
Composite is the pattern to use when you have collections of objects with<br />
whole-part(container within container) relationships and you want to be<br />
able to treat those objects uniformly.<br />
<br />
HeadFirst: Tell us a little more about how these composite and leaf objects are structured.<br />
<br />
Composite: Usually it’s a tree structure, some kind of hierarchy. The root<br />
is the top level composite, and all its children are either composites or leaf nodes.<br />
<br />
Caching: Sometimes, if the composite structure is complex or expensive to traverse,<br />
it’s helpful to implement caching of the composite nodes. For instance, if<br />
you are constantly traversing a composite and all its children to compute<br />
some result, you could implement a cache that stores the result temporarily to save traversals.<br />
<br />
What do you consider your greatest strength?<br />
Composite: I think I’d definitely have to say simplifying life<br />
for my clients. My clients don’t have to worry about whether<br />
they’re dealing with a composite object or a leaf object, so they<br />
don’t have to write if statements everywhere to make sure they’re<br />
calling the right methods on the right objects. Often, they can make<br />
one method call and execute an operation over an entire structure.<br />
<br />
An Iterator takes the job of iterating over an aggregate and encapsulates<br />
it in another object.<br />
<br />
The Composite Pattern allows clients to treat composites and individual objects uniformly.<br />
<br />
There are many design tradeoffs in implementing Composite. You need<br />
to balance transparency and safety with your needs.(between uniformity<br />
of and unwanted method implementation by both leaf node and composite node.)<br />
<br />
The State Pattern ===><br />
<br />
Allows an object to alter its behavior when its internal state<br />
changes. The object will appear to change its class.<br />
<br />
The State and Strategy Patterns have the same class diagram, but they differ in<br />
intent.<br />
<br />
Strategy Pattern - allows client to change its behavior by choosing another object(object composition); also there is no inherent sequence among different behaviors chosen by the client.<br />
<br />
State Pattern - allows the Context class to change its behavior by choosing a different state object everytime. But here, the sequence of states the Context class goes through is determined already(though it can have multiple sequences). Either the Context class or the state object can change the state to another state object.<br />
<br />
Context objects change state over time according to some well defined state<br />
transitions. In other words, changing behavior is built in to its scheme – it’s how I work!<br />
<br />
Using the State Pattern will typically result in a greater number of classes in your<br />
design.<br />
<br />
The Proxy Pattern ===><br />
<br />
Provides a surrogate or placeholder for another object to control access to it.<br />
<br />
Use the Proxy Pattern to create a representative object that controls access<br />
to another object, which may be remote, expensive to create or in need of securing.<br />
<br />
ß As we know, a remote proxy controls access to a remote object.<br />
ß A virtual proxy controls access to a resource that is expensive to create.<br />
ß A protection proxy controls access to a resource based on access rights.<br />
<br />
Sometimes Proxy and Decorator look very similar, but their purposes are<br />
different: a decorator adds behavior to a class, while a proxy controls access<br />
to it.<br />
<br />
a specialized form of a Virtual Proxy called a Caching Proxy. A caching proxy<br />
maintains a cache of previously created objects and when a request is made it<br />
returns cached object, if possible.<br />
<br />
Both Proxy and Adapter sit in front of other objects and forward requests to them. Remember that Adapter changes the interface of the objects it adapts, while the Proxy<br />
implements the same interface.<br />
<br />
A Protection Proxy may allow or disallow a client access to particular methods<br />
in an object based on the role of the client. In this way a Protection Proxy<br />
may only provide a partial interface to a client, which is quite similar to some<br />
Adapters.<br />
<br />
Of course I sometimes create objects, how do you think a virtual proxy gets its subject!<br />
<br />
decorators only add window dressing; they never get to instantiate anything. like just a dumb proxy!<br />
<br />
Java’s got its own proxy support right in the java.lang.reflect package. With this package, Java lets you create a proxy class on the fly that implements one or more interfaces and forwards method invocations to a class that you specify. Because the actual proxy class is created at runtime, we refer to this Java technology as a dynamic proxy.<br />
<br />
Because Java creates the Proxy class for you, you need a way to tell the Proxy class what to do. You can’t put that code into the Proxy class like we did before, because you’re not implementing one directly. So, if you can’t put this code in the Proxy class, where do you put it? In an InvocationHaner.<br />
<br />
The job of the InvocationHandler is to respond to any method calls on the proxy. Think of the InvocationHandler as the object the Proxy asks to do all the real work after it’s received the method calls.<br />
<br />
What’s a Protection Proxy? It’s a proxy that controls access to an object based on access rights.<br />
<br />
InvocationHandlers implement the behavior of the proxy<br />
<br />
PersonBean getOwnerProxy(PersonBean person) {<br />
return (PersonBean) Proxy.newProxyInstance(<br />
person.getClass().getClassLoader(),<br />
person.getClass().getInterfaces(),<br />
new OwnerInvocationHandler(person));<br />
}<br />
<br />
The Proxy class has a static method called isProxyClass(). Calling this method with a class will return true if the class is a dynamic proxy class. Other than that, the proxy class will act like any other class that implements a particular set of interfaces.<br />
<br />
Q: Are there any restrictions on the types of interfaces I can pass into newProxyInstance()?<br />
<br />
A: Yes, there are a few. First, it is worth pointing out that we always<br />
pass newProxyInstance() an array of interfaces – only interfaces are allowed, no classes. The major restrictions are that all non-public interfaces need to be from the same package. You also can’t have interfaces with clashing method names (that is, two interfaces with a method with the same signature). There are a few other minor<br />
nuances as well, so at some point you should take a look at the fine print on dynamic proxies in the javadoc.<br />
<br />
Q: I heard that in Java 5, I don’t even need to generate stubs anymore either. Is that true?<br />
<br />
A: It sure is. In Java 5, RMI and Dynamic Proxy got together and now stubs are generated dynamically using Dynamic Proxy. The remote object’s stub is a java.lang.reflect.Proxy instance (with an invocation handler) that is automatically generated to handle all<br />
the details of getting the local method calls by the client to the remote object.<br />
So, now you don’t have to use rmic at all; everything you need to get a client talking to a remote object is handled for you behind the scenes.<br />
<br />
Facade -Wraps a bunch of objects to simplify their interface<br />
<br />
Decorator -Wraps another object and provides additional behavior for it<br />
<br />
Proxy -Wraps another object to control access to it<br />
<br />
Adapter -Wraps another object and provides a different interface to it<br />
<br />
Complexity Hiding Proxy hides the complexity of and controls access to a complex set of classes. This is sometimes called the Facade Proxy for obvious reasons. The Complexity Hiding Proxy differs from the Facade Pattern in that the proxy controls access, while the Facade Pattern just provides an alternative interface.<br />
<br />
Copy-On-Write Proxy controls the copying of an object by deferring the copying of an<br />
object until it is required by a client. This is a variant of the Virtual Proxy.<br />
<br />
Habitat: seen in the vicinity of the Java 5’s CopyOnWriteArrayList.<br />
<br />
---<br />
<br />
Compound Pattern ===><br />
<br />
A compound pattern combines two or more patterns into a solution that solves a recurring or general problem.<br />
<br />
====><span class="Apple-tab-span" style="white-space: pre;"> </span>MVC<br />
<br />
================================<br />
Q: Does the controller ever become an observer of the model?<br />
A: Sure. In some designs the controller registers with the model and is notified<br />
of changes. This can be the case when something in the model directly affects the<br />
user interface controls. For instance, certain states in the model may dictate that some<br />
interface items be enabled or disabled. If so, it is really controller’s job to ask the view to update its display accordingly.<br />
<br />
Q: All the controller does is take user input from the view and send it to the<br />
model, correct? Why have it at all if that is all it does? Why not just have the code<br />
in the view itself? In most cases isn’t the controller just calling a method on the<br />
model?<br />
A: The controller does more than just “send it to the model”, the controller is<br />
responsible for interpreting the input and manipulating the model based on that input.<br />
But your real question is probably “why can’t I just do that in the view code?”<br />
You could; however, you don’t want to for two reasons: First, you’ll complicate<br />
your view code because it now has two responsibilities: managing the user interface<br />
and dealing with logic of how to control the model. Second, you’re tightly coupling your<br />
view to the model. If you want to reuse the view with another model, forget it. The<br />
controller separates the logic of control from the view and decouples the view from the<br />
model. By keeping the view and controller loosely coupled, you are building a more<br />
flexible and extensible design, one that can more easily accommodate changes down the<br />
road.<br />
<br />
Patterns involved in MVC<br />
------------------------<br />
As you might have guessed the model uses [Observer] to keep the views and controllers updated on the latest state changes. The view and the controller, on the other hand, implement the [Strategy Pattern]. The controller is the behavior of the view, and it can be easily exchanged with another controller if you want different behavior. The view itself also uses a pattern internally to manage the windows, buttons and other components of the display: the [Composite Pattern].<br />
<br />
a pattern you’ll often see hanging around the MVC trio: the Adapter Pattern.<br />
<br />
adapt the HeartModel to a BeatModel. If we don’t, the view won’t be able to work with the model, because the view only knows how to getBPM(), and the equivalent heart model method is getHeartRate().<br />
<br />
Model 2 Pattern ===><br />
<br />
It wasn’t long after the Web was spun that developers started adapting the MVC to fit the browser/server model. The prevailing adaptation is known simply as “Model 2” and uses a combination of servlet and JSP technology to achieve the same separation of model, view and controller that we see in conventional GUIs.<br />
<br />
Design Patterns and Model 2:<br />
<br />
After implementing the DJ Control for the Web using Model 2, you might be wondering where the patterns went. We have a view created in HTML from a JSP but the view is no longer a listener of the model. We have a controller that’s a servlet that receives HTTP requests, but are we still using the Strategy Pattern? And what about Composite? We have a view that is made from HTML and displayed in a web browser. Is that still the Composite Pattern?<br />
<br />
Model 2 is an adaptation of MVC to the Web Even though Model 2 doesn’t look exactly like “textbook” MVC, all the parts are still there; they’ve just been adapted to reflect the idiosyncrasies of the web browser model. Let’s take another look...<br />
<br />
Q: Does the controller ever implement any application logic?<br />
A: No, the controller implements behavior for the view. It is the smarts that translates the actions from the view to actions on the model.<br />
<br />
The model takes those actions and implements the application logic to decide what to do in response to those actions.<br />
<br />
Q: I’ve seen descriptions of the MVC where the controller is described as a<br />
“mediator” between the view and the model. Is the controller implementing the<br />
Mediator Pattern?<br />
A: We haven’t covered the Mediator Pattern (although you’ll find a summary of<br />
the pattern in the appendix), so we won’t go into too much detail here, but the intent of<br />
the mediator is to encapsulate how objects interact and promote loose coupling by<br />
keeping two objects from referring to each other explicitly. So, to some degree, the<br />
controller can be seen as a mediator, since the view never sets state directly on the<br />
model, but rather always goes through the controller. Remember, however, that the<br />
view does have a reference to the model to access its state. If the controller were truly a mediator, the view would have to go through the controller to get the state of the model as well.<br />
<br />
Q: If I have more than one view, do I always need more than one controller?<br />
A: Typically, you need one controller per view at runtime; however, the same<br />
controller class can easily manage many views.<br />
<br />
Q: The view is not supposed to manipulate the model, however I noticed<br />
in your implementation that the view has full access to the methods that change<br />
the model’s state. Is this dangerous?<br />
A: You are correct; we gave the view full access to the model’s set of methods.<br />
We did this to keep things simple, but there may be circumstances where you want to<br />
give the view access to only part of your model’s API. There’s a great design pattern<br />
that allows you to adapt an interface to only provide a subset. Can you think of it?<br />
<br />
We have a new category! MVC and Model 2 are compound patterns<br />
<br />
The Adapter Pattern can be used to adapt a new model to an existing view and controller.<br />
<br />
The view uses the Composite Pattern to implement the user interface, which usually<br />
consists of nested components like panels, frames and buttons.<br />
<br />
Model 2 is an adaptation of MVC for web applications.<br />
<br />
In Model 2, the controller is implemented as a servlet and JSP & HTML implement the<br />
view.<br />
<br />
A Pattern is a solution to a [recurring] problem in a context<br />
<br />
The context is the situation in which the pattern applies. This should be a recurring situation. The problem refers to the goal you are trying to achieve in this<br />
context, but it also refers to any constraints that occur in the context.<br />
The solution is what you’re after: a general design that anyone can apply which resolves the goal and set of constraints.<br />
<br />
Pattern = Recurring[Context + Goals and constraints + Solution]<br />
<br />
Example: You have a collection of objects.<br />
You need to step through the objects without exposing the collection’s<br />
implementation. Encapsulate the iteration into a separate class.<br />
<br />
“If you find yourself in a context with a problem that has a goal<br />
that is affected by a set of constraints, then you can apply<br />
a design that resolves the goal and constraints and leads to a<br />
solution.”<br />
<br />
The Design Pattern definition tells us that the problem consists of a<br />
goal and a set of constraints. Patterns gurus have a term for these: they call them<br />
forces.<br />
<br />
Forces = Goals + Constraints<br />
<br />
Only when a solution balances both sides of the force (the light side: your goal, and the dark side: the constraints) do we have a useful pattern.<br />
<br />
classic GoF catalog; it contains 23 fundamental Design Patterns.<br />
<br />
Frank: GoF?<br />
Jim: Right, that stands for the Gang of Four. The Gang of Four are<br />
the guys that put together the first patterns catalog.<br />
<br />
Creational patterns involve object instantiation and all provide a way to decouple a client from the objects it needs to instantiate.<br />
<br />
Creational: Singleton, Abstract Factory, Factory Method, Builder, Prototype<br />
<br />
Any pattern that is a Behavioral Pattern is concerned with how<br />
classes and objects interact and distribute responsibility.<br />
<br />
Behavioral: Template Method, Iterator, Command, Observer, State, Strategy, Mediator, Visitor, Memento, Interpreter, Chain-of-responsibility<br />
<br />
Structural patterns let you compose classes or objects into larger structures.<br />
<br />
Structural: Proxy, Facade, Decorator, Composite, Adapter, Flyweight, Bridge<br />
<br />
Class patterns describe how relationships between<br />
classes are defined via inheritance. Relationships in<br />
class patterns are established at compile time.<br />
<br />
Class Pattterns: Template Method, Factory Method, Adapter, Interpreter<br />
(if the word 'Method' comes in the name of the pattern, then, subclass methods are involved in the pattern)<br />
<br />
Object patterns describe relationships between objects and are primarily<br />
defined by composition. Relationships in object patterns are typically<br />
created at runtime and are more dynamic and flexible.<br />
<br />
Object Patterns: Composite , Decorator, Proxy, Strategy, Bridge, Flyweight, Abstract Factory, Singleton, Builder, Prototype, State, Mediator, Chain of responsibility, Observer, Facade, Command, Memento, Iterator, Visitor<br />
<br />
Patterns can introduce complexity, and we never want<br />
complexity where it is not needed. But patterns are powerful when used<br />
where they are needed. As you already know, patterns are proven<br />
design experience that can be used to avoid common mistakes. They’re<br />
also a shared vocabulary for communicating our design to others.<br />
<br />
Put simply, “the GoF,” which includes Erich Gamma, Richard<br />
Helm, Ralph Johnson and John Vlissides, is the group of guys who<br />
put together the first patterns catalog and in the process, started an<br />
entire movement in the software field!<br />
<br />
An Anti-Pattern tells you how to go from a problem to a BAD solution.<br />
<br />
Think about it like this: if there is a recurring bad solution to a<br />
common problem, then by documenting it we can prevent other<br />
developers from making the same mistake. After all, avoiding bad<br />
solutions can be just as valuable as finding good ones!<br />
<br />
----------------------<br />
Anti-Pattern ===><br />
----------------------<br />
Name: Golden Hammer<br />
Problem: You need to choose technologies for<br />
your development and you believe that exactly one<br />
technology must dominate the architecture.<br />
Context: You need to develop some new system<br />
or piece of software that doesn’t fit well with the<br />
technology that the development team is familiar with.<br />
Forces:<br />
• The development team is committed to the<br />
technology they know.<br />
• The development team is not familiar with<br />
other technologies.<br />
• Unfamiliar technologies are seen as risky.<br />
• It is easy to plan and estimate for<br />
development using the familiar technology.<br />
Supposed Solution: Use the familiar technology<br />
anyway. The technology is applied obsessively to<br />
many problems, including places where it is clearly<br />
inappropriate.<br />
Refactored Solution: Expanding the knowledge of<br />
developers through education, training, and book<br />
study groups that expose developers to new solutions.<br />
Examples:<br />
Web companies keep using and maintaining their<br />
internal homegrown caching systems when open<br />
source alternatives are in use.<br />
---------------------------<br />
<br />
<br />
Bridge Pattern ===><br />
<br />
Bridge Benefits<br />
ß Decouples an implementation so that it is not bound permanently to an interface.<br />
ß Abstraction and implementation can be extended independently.<br />
ß Changes to the concrete abstraction classes don’t affect the client.<br />
<br />
Bridge Uses and Drawbacks<br />
<br />
ß Useful in graphic and windowing systems that need to run over multiple platforms.<br />
ß Useful any time you need to vary an interface and an implementation in different ways.<br />
ß Increases complexity.<br />
<br />
Bridge - allows to vary both implementation and abstraction<br />
<br />
Builder Pattern ===><br />
<br />
Builder - when an object needs to be constructed differently each time, it can be abstracted into a builder class. Client deals with builder interface/supertype only<br />
<br />
Chain of Responsibility Pattern ===><br />
<br />
Chain of Responsibility - when you want to give more than one object a chance to handle a request. Each object in the chain acts as a handler and has a successor object. If it<br />
can handle the request, it does; otherwise, it forwards the request to its successor.<br />
<br />
-Commonly used in windows systems to handle events like mouse clicks and keyboard events.<br />
-Can be hard to observe the runtime characteristics and debug.<br />
<br />
Flyweight Pattern(one real many virtual objects) ===><br />
<br />
(one object emulating the presence of many objects by maitaining all their states)<br />
<br />
when one instance of a class can be used to provide many “virtual instances.”<br />
<br />
What if, instead of having thousands of Tree objects, you<br />
could redesign your system so that you’ve got only one<br />
instance of Tree, and a client object that maintains the state<br />
of ALL your trees? That’s the Flyweight!<br />
<br />
All the state, for ALL of your virtual Tree objects, is stored in 2D-array in the client object.<br />
<br />
Interpreter Pattern(language interpretation) ===> to build an interpreter for a language.<br />
<br />
Interpreting a language through set of Expression concrete classes which are related via inheritance and composition.<br />
<br />
Mediator Pattern(star topology) ===> to centralize complex communications and control between related objects.<br />
<br />
Mediator sits in the middle of the star topology in order to decouple surrounding objects from each other but still allow them to communicate with each other through mediator.<br />
<br />
The Memento ====> (Saving EMS Switch GUI state)<br />
<br />
has two goals:<br />
<br />
ß Saving the important state of a system’s key object.<br />
ß Maintaining the key object’s encapsulation.<br />
<br />
Client can do save and restore operation on a key object using this pattern.<br />
<br />
Prototype Pattern ===><br />
<br />
when creating an instance of a given class is either expensive or<br />
complicated.<br />
<br />
The Prototype Pattern allows you to make new instances by<br />
copying existing instances. A key aspect of this pattern is that the client code can<br />
make new instances without knowing which specific class is<br />
being instantiated.<br />
<br />
Benefits<br />
-------<br />
ß Hides the complexities of making new instances from<br />
the client.<br />
ß Provides the option for the client to generate objects<br />
whose type is not known.<br />
ß In some circumstances, copying an object can be<br />
more efficient than creating a new object.<br />
<br />
Visitor Pattern ===><br />
<br />
when you want to add capabilities to a composite of objects<br />
and encapsulation is not important.<br />
<br />
when new operation is needed to be performed, client asks the visitor to do it without changing the structure of the target composite object.<br />
<br />
e.g. a datastructure presents all elements to the visitor and lets the visitor decide what to do with them<br />
<br />
===========================x=========================<br />
<div>
<br /></div>
<div>
<b>Reference</b>: Head First</div>
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-11914567928935426002012-05-30T07:31:00.000+05:302012-05-30T07:31:00.250+05:30GIST NOTES 12 - Algorithms and Data Structures<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 12 - Algorithms and Data Structures</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
To understand these notes, you may want to complete reading a book on this subject.<br />
<br />
<br />
>One goal of sorting is to facilitate searching<br />
>the no.of comparisons is a rough measure of efficiency in any sorting algorithm<br />
>simple sorts: straight selection sort, bubble sort and insertion sort [they use brute force]<br />
>more complex (hence more efficient) sorts: merge sort, quick sort, heap sort<br />
>Big O - Order of magnitude<br />
>O(n) - when n is large other components in the equation are negligible<br />
>O(n^2) - when n is large, compared to n^2, other terms of the function are negligible<br />
>O(1) is called bounded time<br />
>O(log2(n)) - logarithmic time<br />
>O(n) - is linear time<br />
>O(n*log2(n)) - n times log2(n) ; [quick/merge/heap sorts]<br />
>O(n^2) - quadratic time<br />
>O(2^n) - exponential time; These algorithms are extremely costly. An example<br />
of a problem for which the best known solution is exponential is the traveling salesman<br />
problem—given a set of cities and a set of roads that connect some of them, plus the<br />
lengths of the roads, find a route that visits every city exactly once and minimizes total<br />
travel distance. As you can see in Table 3.3, exponential times increase dramatically in<br />
relation to the size of N. (It also is interesting to note that the values in the last column<br />
grow so quickly that the computation time required for problems of this order may<br />
exceed the estimated life span of the universe!)<br />
<br />
>selection/bubble/insertion sorts are of order O(n^2)<br />
>merge/quick/heap sorts employ divide and conquer approach because N^2 rapidly decreases mathematically when treated as (N/2)^2 + (N/2)^2<br />
>merge sort - log2(n) divide levels and n comparisons in each merge no matter how many merges needed in each divide level<br />
>quick sort - only if the pivot in each level divides the list into two equal halves, we get log2(n) levels; otherwise, the split levels could go up to n-1 levels degrading the quick sort from its best performance of n*log2(n) to n*(n-1) which is n^2; so the choice of the pivot in each level matters a lot<br />
<br />
>merge sort needs extra temp array for sorting but quick sort does not need<br />
>every recursive algorithm needs extra space to save the calls on stack when moving deep in recursion<br />
>divide and conquer algorithms which split the list in half in each recursion need log2(n) recursive calls and hence log2(n) stack size to save method call context<br />
>quick sort doesn't need to explicitly join left-list,pivot and right-list because the algorithm is performed in-place within the given list<br />
>the in-place quick sort first selects a pivot-index and calls partition method to get a new pivot-index; using this new pivot-index only it further recurses to left and right list not the chosen pivot-index; this signifies that the partition method since it does in-place adjustments, the pivot value itself has to be moved to accommodate values less than pivot on left side and values greater than pivot on right side (gotcha?)<br />
<br />
>heap with complete binary tree: Removing top element and reheapifying(assume an array holding the heap): In this process a hole is left at the top of the tree namely root's position. Now the intention is to find the next biggest element in the tree(which will definitely be in the next level to the hole, namely hole's children) and to move the last element somewhere to the front so that elements occupy one less space in the array due to the removal of the root:<br />
<br />
Here, we move the hole down to next level as long as one of the hole's children is greater than the last element in the array; this signifies that when we pick one of root's children to be root, the heap order is not disturbed; if none of the hole's children is greater than the last element in the array, then move the last element of the array to the current hole; this signifies that we have moved the hole down as far as possible and found a new home to the last element of the array<br />
<br />
>there are no better algorithms than O(n*log2(n)) for comparison based algorithms<br />
>avoid new method calls and prefer inline codes instead; prefer non-recursive version instead of recursive version to improve the performance of sorting algorithms<br />
>inherently unstable sorting algorithms are heap sort and quick sort<br />
<br />
>binary search is better than linear search generally when N is larger<br />
>binary search works only on arrays; for linked list based structures, binary search is done in the form of binary search tree<br />
<br />
[Data Structures by Nell Dale - Good book, always concentrates on most complex methods]<br />
<br />
>collision - when hashing produces same value for two items<br />
>linear probing - when collision happens, start searching sequentially from the location returned by the hash function<br />
>clustering - tendency of elements to become unevenly distributed in the hash table, with many elements clustering around a single location<br />
>rehashing - resolving a collision by computing a new hash value based on the original location(colliding hash value) rather than the item key<br />
>Quadratic probing - Resolving a hash collision by using the rehashing formula (HashValue + I2)% array-size, where I is the number of times<br />
that the rehash function has been applied<br />
>Random probing - Resolving a hash collision by generating pseudo-random hash values in successive applications of the rehash function<br />
>bucket - a collection of elements associated with a particular hash location<br />
>chain - a linked list of elements that share the same hash location<br />
>folding - a hash method that breaks the key into several pieces and concatenates or XORs some of them to form the hash value<br />
<br />
>In binary search tree, while deleting or inserting nodes, reconnecting the tree is done by recursive calls and reassignments of nodes at each level; this is needed because, children do not have back references to parent and hence while recursion call goes down from parent, make sure to reassign parent or its children with the result returned by the recursive call; also while inserting and deleting, they don't care about the shape of the tree; later may be one can rebalance the tree;<br />
<br />
>to balance a tree, pick the element whose value is in the middle(which sits in between smallest and biggest elements of the tree) which divides the elements into two halves. Put the middle element as root and insert the rest of the elements on left and right subtree without ever changing the root again. Use INORDER to store the tree elements in an array which sorts the elements in ascending order automatically (need to check this approach works or not)<br />
<br />
OFFICIAL ALGO:<br />
<br />
Balance<br />
<br />
Set count to tree.reset(INORDER).<br />
For (int index = 0; index < count; index++)<br />
Set array[index] = tree.getNextItem(ORDER).<br />
tree = new BinarySearchTree().<br />
tree.InsertTree(0, count-1)<br />
<br />
<br />
InsertTree(low, high)<br />
<br />
if (low == high) // Base case 1<br />
tree.insert(nodes[low]).<br />
else if ((low + 1) == high) // Base case 2<br />
tree.insert(nodes[low]).<br />
tree.insert(nodes[high]).<br />
else<br />
mid = (low + high) / 2.<br />
tree.insert(mid).<br />
tree.InsertTree(low, mid – 1).<br />
tree.InsertTree(mid + 1, high).<br />
<br />
>to replicate or clone a tree, save the tree in preorder in an array and recreate the new tree from the array; preorder always inserts the parent node first before inserting the children and hence it maintains the parent child relationship from the original tree<br />
<br />
>in trees, every node has only one parent; in graphs each node can have more than one parent<br />
<br />
>graphs - connected edges and vertices<br />
<br />
>graphs can be directed(called digraph) or undirected(two-way)<br />
<br />
>adjacent vertices - if the vertices are connected by an edge<br />
<br />
>a binary tree is a special case of a directed graph(downward directed)<br />
<br />
>consider an edge A----->B in which A is said to be "adjacent to B" and B is said to be "adjacent from A"<br />
<br />
>A tree is a special case of a directed graph in which each vertex may only be adjacent from one<br />
other vertex (its parent node) and one vertex (the root) is not adjacent from any other vertex.<br />
<br />
>A complete graph is one in which every vertex is adjacent to every other vertex.<br />
<br />
>A weighted graph is a graph in which each edge carries a value. Weighted graphs<br />
can be used to represent applications in which the value of the connection between the<br />
vertices is important, not just the existence of a connection.<br />
<br />
>spanning tree -> v-1 edges connecting all v vertices in the graph is called a spanning tree<br />
>minimum spanning tree -> a spanning tree which has minimum total cost<br />
>Minimum Spanning Tree(MST) - Kruskal's algorithm<br />
<br />
This algorithm creates a forest of trees. Initially the forest consists of n single node trees (and no edges). At each step, we add one (the cheapest one) edge so that it joins two trees together. If it were to form a cycle, it would simply link two nodes that were already part of a single connected tree, so that this edge would not be needed.<br />
The basic algorithm looks like this:<br />
<br />
Forest MinimumSpanningTree( Graph g, int n, double **costs ) {<br />
Forest T;<br />
Queue q;<br />
Edge e;<br />
T = ConsForest( g );<br />
q = ConsEdgeQueue( g, costs );<br />
for(i=0;i<(n-1);i++) {<br />
do {<br />
e = ExtractCheapestEdge( q );<br />
} while ( !Cycle( e, T ) );<br />
AddEdge( T, e );<br />
}<br />
return T;<br />
}<br />
The steps are:<br />
The forest is constructed - with each node in a separate tree.<br />
The edges are placed in a priority queue.<br />
Until we've added n-1 edges,<br />
Extract the cheapest edge from the queue,<br />
If it forms a cycle, reject it,<br />
Else add it to the forest. Adding it to the forest will join two trees together.<br />
Every step will have joined two trees in the forest together, so that at the end, there will only be one tree in T.<br />
We can use a heap for the priority queue. The trick here is to detect cycles. For this, we need a union-find structure.<br />
<br />
>>Djikstra's algorithm (named after its discover, E.W. Dijkstra) solves the problem of finding the shortest path from a point in a graph (the source) to a destination. It turns out that one can find the shortest paths from a given source to all points in a graph in the same time, hence this problem is sometimes called the single-source shortest paths problem.<br />
<br />
initialise_single_source( Graph g, Node s )<br />
for each vertex v in Vertices( g )<br />
g.d[v] := infinity<br />
g.pi[v] := nil<br />
g.d[s] := 0;<br />
<br />
<br />
d<span class="Apple-tab-span" style="white-space: pre;"> </span> array of best estimates of shortest path to each vertex<br />
pi<span class="Apple-tab-span" style="white-space: pre;"> </span>an array of predecessors for each vertex<br />
<br />
relax( Node u, Node v, double w[][] )<br />
if d[v] > d[u] + w[u,v] then<br />
d[v] := d[u] + w[u,v]<br />
pi[v] := u<br />
The algorithm itself is now:<br />
shortest_paths( Graph g, Node s )<br />
initialise_single_source( g, s )<br />
S := { 0 } /* Make S empty */<br />
Q := Vertices( g ) /* Put the vertices in a PQ */<br />
while not Empty(Q)<br />
u := ExtractCheapest( Q );<br />
AddNode( S, u ); /* Add u to S */<br />
for each vertex v in Adjacent( u )<br />
relax( u, v, w )<br />
<br />
>>Huffman algorithm - uses binary max heap to encode symbols with efficient binary bit streams (of varying length); infrequent symbols(chars) go farther from root; frequent symbols get closer to root; weight of each node being the frequency(of occurrence) of the symbol, parent node's weight is the sum of its children weights.<br />
<br />
The algorithm, keeps forming the binary heap tree, as new nodes are added.<br />
<br />
> the order of insertion decides the shape of the tree; random order gives balanced tree<br />
<br />
>Heapyfying - adding a new item to heap involves moving the hold from leaf to root upwards<br />
- removing an item from heap involves moving the hole(created by the removal of the node) downwards<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
><br />
<br />
>>java HashMap uses linked-list(chaining) to resolve collisions<br />
<br />
>>random number sequence - not arbitrary number; but having a property of every number in the range can equally occur<br />
>pseudo random numbers - any man made random number generator once its implementation logic is known it is no longer random; but the number sequence generated has many mathematical properties of real random number sequence; hence we call these pseudo random number generators/sequence<br />
>quasi random number sequence - certain chosen random distribution property is met but not other properties<br />
>random number generation methods: 1. linear congruential method, and 2. additive congruential method<br />
<br />
1. linear - using modulus operator, a multiplier and adding one to the current item will produce next item in the random sequence (currentItem * c + 1) % m; here m decides the range within which the random numbers occur(0 to m-1); xxxE21 form numbers work well when chosen as constant c, where E is an even digit<br />
<br />
2. additive - an arbitrary content is available in a register(bit register); xor right most two bits; right shift the register by one position; fill the left most void with xor'ed result - vola! you have a new random number! keep doing this to produce sequence of random numbers<br />
<br />
>>sorting methods - Basically, the methods divide into three<br />
types: those that sort in place and use no extra memory except perhaps for<br />
a small stack or table; those that use a linked-list representation and so use<br />
N extra words of memory for list pointers; and those that need enough extra<br />
memory to hold another copy of the array to be sorted.<br />
<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-10716263448781276782012-05-29T07:28:00.000+05:302012-07-17T23:17:45.290+05:30GIST NOTES 11 - Advanced Concurrency and Non-blocking Threads<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: large;">GIST NOTES 11 - Advanced Concurrency and Non-blocking Threads</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
[JDK 7]<br />
<br />
<br />
======================<br />
CONCURRENT PROGRAMMING<br />
======================<br />
>in concurrent programming there are two basic units of execution; 1.processes and 2. threads<br />
>concurrency or the effect of concurrency is possible even in single processor systems; but gives enhanced performance in multiprocessor systems which are common today<br />
<br />
Processes<br />
----------<br />
>a process is a self contained execution environment<br />
>it has a complete, private set of basic run-time resources particularly memory space<br />
>processes can be seen as programs or applications however, an application can be a set of cooperating processes<br />
>to facilitate communication between processes, most operating systems support Inter Process Communication(IPC) resources<br />
>such resources may be pipes or sockets<br />
>IPC is not just for communication between processes on the same system, but also for processes running on different systems<br />
>most JVM implementations run as a single process; a java application can create additional processes using ProcessBuilder object<br />
<br />
Threads<br />
-------<br />
>threads are sometimes called as lightweight processes(LWP)<br />
>both processes and threads provide an execution environment<br />
>but creating a new thread requires fewer resources than creating a new process<br />
>threads exist within a process; every process has at least one thread<br />
>threads share the resources (like memory and open files) of the process under which they run<br />
>this makes for efficient but potentially problematic communication among threads<br />
<br />
>every java application has at least one thread(along with several system threads of course); user always starts with 'main' thread when he runs the java app<br />
<br />
>one thread can interrupt another thread; on such occasion it is a general programming practice for the interrupted thread to return from whatever it was doing<br />
<br />
>suppose, a thread didn't receive InterruptedException for long time; how can it check whether it has received any interrupts or not?<br />
>it can call Thread.interrupted() method which returns true if there was any pending interrupt signals for this thread; if true the thread can return from its work or waiting status; interrupted() method clears the interrupted flag when called, so that it can receive next interrupt signals on that boolean variable<br />
>upon the detection of interrupt, the thread can throw InterruptedException in order to propagate the signal to a centralized exception handler<br />
<br />
Interrupt status flag<br />
---------------------<br />
>this flag is maintained internally in every thread<br />
>[non static]Thread.interrupt() can set this flag<br />
>[static]Thread.interrupted() returns the flag and clears it(this method can be used by the owner thread only)<br />
>[non static]Thread.isInterrupted() returns the flag leaving the flag status intact; this method is used by other threads to check this thread<br />
>By convention any method that exits by throwing InterruptedException, clears interrupt flag on exit; however another thread might set interrupt flag to true immediately again<br />
<br />
>join() and sleep() have overloaded methods to specify time out; both of them throw InterruptedException upon interrupt() call on this thread by other threads<br />
<br />
>interrupt(), interrupted(), isInterrupted()<br />
<br />
Thread Interference<br />
-------------------<br />
>corrupting the shared data (shared by multiple threads)<br />
<br />
Memory Consistency Errors<br />
-------------------------<br />
>errors that occur due to inconsistent 'view' of the shared data by a thread<br />
<br />
>to avoid this error, an understanding of happens-before relationship is required<br />
>this relationship ensures that memory writes are visible and apparent for every thread; because write happens before other thread reads; one of the things that create happens-before relationship is synchronization<br />
>two more such things are Thread.start() and Thread.join()<br />
>Thread.start() every statement before this call happen before all the statements of the new thread<br />
>Thread.join() all statements of target(which is joined by another) thread happen before the subsequent statements of the joining thread<br />
>synchronized keyword before constructor is illegal<br />
>no need to synchronize constructors because, only one thread has access to an object which is being constructed through constructors<br />
>but before that make sure that the reference to the object which is being constructed(through constructor call) is not leaked prematurely; like adding 'this' reference to a shared list inside the constructor will create concurrency issues<br />
>synchronized methods are simple solutions to avoid thread interference and memory consistency errors<br />
<br />
>final fields can be safely read through non-synchronized methods, but still 'liveness' problem can occur due to this<br />
<br />
Intrinsic lock or monitor lock<br />
------------------------------<br />
>this locks provide both exclusive access and happens-before relationship essential to visibility<br />
>these are nothing but object locks in java used internally for synchronized methods and blocks<br />
>synchronizing unwanted code can cause 'liveness' problem<br />
>synchronized blocks allow use of multiple locks for different sections of code, and allow to keep unwanted code lines from being synchronized<br />
<br />
Reentrant synchronization<br />
-------------------------<br />
>a thread can acquire a lock it already owns again and again<br />
>this facility enables reentrant synchronization<br />
>hence easy to call another synchronized method for which the already acquired lock is sufficient<br />
>without reentrant synchronization, a thread can block itself forever and to avoid that, requires additional precautions<br />
<br />
Atomic Action<br />
-------------<br />
>all steps happen at once; nobody can come in between<br />
<br />
What are/aren't already atomic in java?<br />
---------------------------------------<br />
1.read or write for reference variables ARE<br />
2.read or write for primitives except double and long ARE<br />
3.read or write for volatile variables of all kinds ARE(reference, primitives including long & double)<br />
4.increment/decrement operations ARE NOT atomic<br />
<br />
>atomic operations cannot be interleaved hence they can be used without the fear of thread interference<br />
>use of volatile variables reduces the risk of memory consistency errors<br />
>because writing volatile variables ensures happens-before relationship with subsequent reads of that variable(what a humbo jumbo about happens-before stuff? I don't understand a thing. Well, remember everybody is forced to not keep any cached data for volatile variables? so when someone writes a volatile variable, everyone who reads subsequently will by default by the design of volatile variable and its rules, get the latest update; hence, any volatile variable write has the happens-before relationship with any upcoming reads)<br />
>not only the latest writes of volatile variables are visible to all threads; but also the side effects of the code that updated is also visible to all threads<br />
<br />
>using atomic variables is more efficient than synchronized codes; but lot of responsibility(to avoid memory consistency errors) is left to users of atomic variables, which is not the case for synchronized codes; that is in sychronized coded applications, threads can be dumb and not care about the way other threads might change the shared data; but in atomic variable situation, threads have to be aware of everyone else and their actions on the shared data and how they can screw the data up;<br />
<br />
>so the choice between atomic variables and synchronized code depends on the size and complexity of the application<br />
<br />
Liveness: ability of a concurrent application to execute in a timely manner<br />
--------<br />
<br />
Liveness Problems: deadlock, starvation and livelock<br />
<br />
Common one: deadlock - blocked by each other(everybody is waiting for each other)<br />
Less common ones: starvation and livelock<br />
<br />
Starvation: a thread not able to gain regular access and unable to progress; happens when a greedy thread hogs the shared resources; for example when a synchronized method takes long time to return and that method is called by a thread frequently, other threads that need frequent access to other methods on the same object will be often blocked<br />
<br />
Livelock: here threads are not blocked as in deadlock; they are simply too busy responding to each other to resume work; they get tangled up in responses only never moving on to resume the work; similar to two people attempting to pass each other in a corridor; happens when both the threads are being nice to each other blindly, not realizing that they are doing an awkward dancing(eek!)<br />
<br />
Guarded Blocks<br />
--------------<br />
>certain block of code has to be entered upon meeting a specific condition only<br />
>instead of waiting for the condition on a CPU wasteful loop, use wait() notifyAll() mechanism of threads<br />
>Note: There is a second notification method, notify, which wakes up a single thread. Because notify doesn't allow you to specify the thread that is woken up, it is useful only in massively parallel applications — that is, programs with a large number of threads, all doing similar chores. In such an application, you don't care which thread gets woken up.<br />
<br />
A Strategy for Defining Immutable Objects(no need for synchronization for these)<br />
-----------------------------------------<br />
The following rules define a simple strategy for creating immutable objects. Not all classes documented as "immutable" follow these rules. This does not necessarily mean the creators of these classes were sloppy — they may have good reason for believing that instances of their classes never change after construction. However, such strategies require sophisticated analysis and are not for beginners.<br />
Don't provide "setter" methods — methods that modify fields or objects referred to by fields.<br />
Make all fields final and private.<br />
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.<br />
If the instance fields include references to mutable objects, don't allow those objects to be changed:<br />
Don't provide methods that modify the mutable objects.<br />
Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>--x--<br />
<br />
java.util.concurrent.locks<br />
--------------------------<br />
>a framework for locking and waiting for conditions that is distinct from built-in synchronization and monitors<br />
>Lock replaces use of synchronized methods and statements<br />
>a Condition replaces the use of the Object monitor methods<br />
<br />
Lock<br />
----<br />
The use of synchronized methods or statements provides access to the implicit monitor lock associated with every object, but forces all lock acquisition and release to occur in a block-structured way: when multiple locks are acquired they must be released in the opposite order, and all locks must be released in the same lexical scope in which they were acquired.<br />
<br />
While the scoping mechanism for synchronized methods and statements makes it much easier to program with monitor locks, and helps to avoid many common programming errors involving locks, there are occasions where you need to work with locks in a more flexible way. For example, some algorithms for traversing concurrently accessed data structures require the use of "hand-over-hand" or "chain locking": you acquire the lock of node A, then node B, then release A and acquire C, then release B and acquire D and so on. Implementations of the Lock interface enable the use of such techniques by allowing a lock to be acquired and released in different scopes, and allowing multiple locks to be acquired and released in any order.<br />
<br />
With this increased flexibility comes additional responsibility. The absence of block-structured locking removes the automatic release of locks that occurs with synchronized methods and statements. In most cases, the following idiom should be used:<br />
<br />
Lock l = ...;<br />
l.lock();<br />
try {<br />
// access the resource protected by this lock<br />
} finally {<br />
l.unlock();<br />
}<br />
<br />
When locking and unlocking occur in different scopes, care must be taken to ensure that all code that is executed while the lock is held is protected by try-finally or try-catch to ensure that the lock is released when necessary.<br />
Lock implementations provide additional functionality over the use of synchronized methods and blocks by providing a non-blocking attempt to acquire a lock (tryLock()), an attempt to acquire the lock that can be interrupted (lockInterruptibly(), and an attempt to acquire the lock that can timeout (tryLock(long, TimeUnit)).<br />
<br />
A Lock class can also provide behavior and semantics that is quite different from that of the implicit monitor lock, such as guaranteed ordering, non-reentrant usage, or deadlock detection. If an implementation provides such specialized semantics then the implementation must document those semantics.<br />
<br />
Note that Lock instances are just normal objects and can themselves be used as the target in a synchronized statement. Acquiring the monitor lock of a Lock instance has no specified relationship with invoking any of the lock() methods of that instance. It is recommended that to avoid confusion you never use Lock instances in this way, except within their own implementation.<br />
<br />
The java.util.concurrent package defines three executor interfaces:<br />
-------------------------------------------------------------------<br />
1.Executor, a simple interface that supports launching new tasks.<br />
2.ExecutorService, a subinterface of Executor, which adds features that help manage the lifecycle, both of the individual tasks and of the executor itself.<br />
3.ScheduledExecutorService, a subinterface of ExecutorService, supports future and/or periodic execution of tasks.<br />
<br />
Runnable - a task that returns nothing<br />
Callable - a task that returns something<br />
Future - which helps to retrieve the return value of a Callable; helps to manage the status of Runnable and Callable tasks<br />
<br />
ExecutorService - supports creation and management of Runnable/Callable through Future objects; also supports managing the shutdown of the executor<br />
<br />
Creating Your Own Thread Pool<br />
-----------------------------<br />
>determining thread pool size (fixed or dynamic)<br />
>job addition (single thread or multithreads add jobs)<br />
>workers should be responsive to the manager all the time<br />
>premature shutdown/graceful shutdown of all threads<br />
>manager(or main thread) can wait for all threads to complete through join() method<br />
>workers can wait on empty queue<br />
>nofication is necessary whenever a new job is added to the queue<br />
>when a thread is interrupted from wait() and if the wait() statement is wrapped in try-catch within synchronized block, when the control enters catch block to handle InterruptedException, at this time also it needs the lock on the object; if you put sleep statement inside catch block, it sleeps while holding the lock; no other thread can use the lock;<br />
>the above situation happens if you badly coded the after statements to wait()-try-catch section; because when the manager interrupts all the workers to shutdown, the first interrupted thread can hold the lock in the catch block and sleep forever, and no other thread will be able to proceed to graceful shutdown and thread pool will never shutdown and never do any work either<br />
<br />
>in the middle of an atomic operation do not give up your lock to others; if you do, when you(thread) come back, start the atomic operation all over again(so be mindful of where you put wait() call)<br />
<br />
>PThread - POSIX standard threads usually available in Unix systems; POSIX-Portable Operating System Interface<br />
<br />
Guarded Block - sensitive section of code block that accesses shared data<br />
<br />
Mutex - mutual exclusion mechanism to protect guarded blocks<br />
<br />
Monitor - mechanism to protect guarded blocks using mutex objects such as locks<br />
<br />
Semaphore - alternate mechanism to protect guarded blocks; differs from monitor in the respect that semaphore has more than one identical resources (instead of a single lock in Monitors), and keeps giving them away to each thread, each time keeping track of no.of remaining resources; once all of them are over, it forces new threads to wait; it also doesn't insist on ownership (threads that acquired lock, has complete ownership over it and it can decide when to release) to threads as in Monitors<br />
<br />
Dining philosopher problem - thread contention illustrated by shared forks<br />
<br />
IPC Communication Through: sockets, signal handlers, shared memory, semaphores, and files<br />
<br />
<br />
-----------------------------------------------------------------------------------------------<br />
Java Concurrency In Practice By Brian, Tim, Joshua, Joseph, David and Doug Lea<br />
-----------------------------------------------------------------------------------------------<br />
[Reading this book gives you nightmares. It is like, all you know about java for-sure, go wrong in concurrent environment]<br />
<br />
Threads are more basic units of scheduling than processes.<br />
<br />
Since threads share same heap/memory and resources from their process, they can communicate more efficiently.<br />
<br />
Threads are useful in GUI applications for improving responsiveness of the user interface, and in server applications for improving resource utilization and throughput.<br />
<br />
They simplify the implementation of JVM(GC usually runs in one or more dedicated threads).<br />
<br />
Java java.nio is for non-blocking IO(was developed for the use of single threaded programs which cannot be blocked).<br />
<br />
[[[Frameworks(such as servlets, RMI, etc) introduce concurrency into applications by calling application components from framework threads. Components invariably access application state, that requiring that all code paths accessing that state be thread-safe.]]]<br />
<br />
Use of the following could introduce concurrency issues into your SINGLE threaded program<br />
-----------------------------------------------------------------------------------------<br />
>Timer - TimerTasks might access shared data in future in parallel to your application<br />
>Servlets and Java Server Pages(JSP) - servlets need to be thread safe because to handle high volume http requests, multiple threads are employed by the webserver; even if a servlet is used by one thread, it still could access application wide objects like ServletContext(application-scoped) or shared session-objects(HttpSession)<br />
>RMI - remote object calls happen in their own threads created by RMI framework; so remote objects should ensure concurrent access for themselves as well as the data objects they expose<br />
>Swing and AWT - GUI apps are inherently asynchronous; to ensure responsiveness of GUI at all times, Swing and AWT create a separate thread for handling user-initiated events, and to update the GUI visible to the user; Swing components(like JTable) are not thread-safe; instead thread-safety is achieved by confining all access to GUI to a single thread; any code which wants to control GUI should run under the single event-dispatcher thread<br />
<br />
#often it is effective to place synchronization as close to shared data(or within shared data object) so that thread-safety is ensured everywhere<br />
#it is also imperative to see what is atomic at every level of programming; though you use a thread-safe data structure, it may not provide atomicity at your application level, and hence synchronization is needed in your application level as well<br />
<br />
>When designing thread safe classes, good object oriented techniques encapsulation, immutability, and clear<br />
specification of invariants are your best friends.<br />
<br />
>A class is [Thread Safe] when it continues to behave correctly when accessed from multiple threads<br />
<br />
>Thread safe classes encapsulate any needed synchronization so that clients need not provide their own<br />
<br />
>stateless objects(which have no fields, relying only on method local variables) are always thread safe(because local variables on stack are specific to the executing thread and not shared)<br />
<br />
>Sateless Servlets are great because they don't require thread safety codes<br />
<br />
>Race Condition: The possibility of incorrect results in the presence of unlucky timing; the correctness of a computation depends on the relative timing or interleaving of multiple threads by the runtime; in other words, getting the correct result depends on chance factor;<br />
>The most common type of race condition is check-then-act, where a potentially stale observation is used to make a decision on what to do next<br />
>race condition is often confused with a related term data-race; data-race happens when two threads share a non-final field without coordination; happens whenever a thread is trying to write a variable that might be read next by another thread, or trying to read a variable that might have been written by another thread last time; not all race conditions are data races; not all data races are race conditions; but both make application behave unpredictably in concurrent environment<br />
>lazy initialization(initialize only when it is required, and only once) can cause race conditions if not synchronized [e.g. concurrency problem in singleton pattern]<br />
<br />
>Compound Actions - sequences of operations that must be executed atomically in order to remain thread-safe<br />
<br />
>when there is only one state variable(instance field or otherwise), use Atomic data type to ensure thread-safety; when you have more than one state variable in your object, using atomic data type is not just enough<br />
<br />
>to preserve state consistency, update related variables in a single atomic operation<br />
<br />
>intrinsic locks (or monitor locks) in java act as mutexes(mutual exclusion locks)<br />
<br />
>Reentrancy means that locks are acquired on a per-thread rather than perinvocation basis. [7] Reentrancy is implemented by associating with each lock an acquisition count and an owning thread. When the count is zero, the lock is considered unheld. When a thread acquires a previously unheld lock, the JVM records the owner and sets the acquisition count to one. If that same thread acquires the lock again, the count is incremented, and when the owning thread exits the synchronized block, the count is decremented. When the count reaches zero, the lock is released.<br />
[7] This differs from the default locking behavior for pthreads (POSIX threads) mutexes, which are granted on a per invocation basis.<br />
<br />
>Reentrancy facilitates encapsulation of locking behavior, and thus simplifies the development of object oriented<br />
concurrent code. Without reentrant locks, the very natural looking code in Listing 2.7, in which a subclass overrides a synchronized method and then calls the superclass method, would deadlock.<br />
<br />
>synchronization is also about visibility of data modifications across all threads (no surprises to any thread)<br />
<br />
>statement reordering(different order from the code) can be done by compiler and JVM memory model and CPU to take advantage of caching data between operations, and for improving performance; this reordering can give the most weirdest results in a concurrent environment where thread-safety is missing<br />
<br />
>3.1.2. Non atomic 64 bit Operations When a thread reads a variable without synchronization, it may see a stale value, but at least it sees a value that was actually placed there by some thread rather than some random value. This safety guarantee is called out of thin air safety. Out of thin air safety applies to all variables, with one exception: 64 bit numeric variables (double and long) that are not declared volatile . The Java Memory Model requires fetch and store operations to be atomic, but for nonvolatile long and double variables, the JVM is permitted to treat a 64 bit read or write as two separate 32 bit operations. If the reads and writes occur in different threads, it is therefore possible to read a nonvolatile long and get back the high 32 bits of one value and the low 32 bits of another.[3] Thus, even if you don't care about stale values, it is not safe to use shared mutable long and double variables in multithreaded programs unless they are declared volatile or guarded by a lock.<br />
[3] When the Java Virtual Machine Specification was written, many widely used processor architectures could not efficiently provide atomic 64 bit arithmetic operations.<br />
<br />
>Locking is not just about mutual exclusion; it is also about memory visibility. To ensure that all threads see the most up to date values of shared mutable variables, the reading and writing threads must synchronize on a common lock.<br />
<br />
>The Java language also provides an alternative, weaker form of synchronization, volatile variables, to ensure that updates to a variable are propagated predictably to other threads. When a field is declared volatile, the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations. Volatile variables are not cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always returns the most recent write by any thread.<br />
<br />
>Use volatile variables only when they simplify implementing and verifying your synchronization policy; avoid using volatile variables when verifying correctness, would require subtle reasoning about visibility. Good uses of volatile variables include ensuring the visibility of their own state, that of the object they refer to, or indicating that an important lifecycle event (such as initialization or shutdown) has occurred.<br />
<br />
>[6] Debugging tip: For server applications, be sure to always specify the -server JVM command line switch when invoking the JVM, even for development and testing. The server JVM performs more optimization than the client JVM, such as hoisting variables out of a loop that are not modified in the loop; code that might appear to work in the development environment (client JVM) can break in the deployment environment (server JVM). For example, had we "forgotten" to declare the variable asleep as volatile in Listing 3.4, the server JVM could hoist the test out<br />
of the loop (turning it into an infinite loop), but the client JVM would not. An infinite loop that shows up in development is far less costly than one that shows up only in production.<br />
<br />
Listing 3.4. Counting Sheep.<br />
volatile boolean asleep;<br />
...<br />
while (!asleep)<br />
countSomeSheep();<br />
<br />
>Locking can guarantee both visibility and atomicity; volatile variables can only guarantee visibility.<br />
<br />
>You can use volatile variables only when all the following criteria are met:<br />
Writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value; The variable does not participate in invariants with other state variables; and Locking is not required for any other reason while the variable is being accessed.<br />
<br />
>Listing 3.6. Allowing Internal Mutable State to Escape. Don't Do this.<br />
class UnsafeStates {<br />
private String[] states = new String[] {<br />
"AK", "AL" ...<br />
};<br />
public String[] getStates() { return states; }<br />
}<br />
<br />
>Publishing states in this way is problematic because any caller can modify its contents. In this case, the states array has escaped its intended scope, because what was supposed to be private state has been effectively made public.<br />
Publishing an object also publishes any objects referred to by its non private fields. More generally, any object that is reachable from a published object by following some chain of non private field references and method calls has also been published.<br />
<br />
>From the perspective of a class C, an alien method is one whose behavior is not fully specified by C. This includes methods in other classes as well as overrideable methods (neither private nor final) in C itself. Passing an object to an alien method must also be considered publishing that object. Since you can't know what code will actually be invoked, you don't know that the alien method won't publish the object or retain a reference to it that might later be used from another thread. Whether another thread actually does something with a published reference doesn't really matter, because the risk of misuse is still present.[7] Once an object escapes, you have to assume that another class or thread may, maliciously or carelessly, misuse it. This is a compelling reason to use encapsulation: it makes it practical to analyze programs for<br />
correctness and harder to violate design constraints accidentally.<br />
[7] If someone steals your password and posts it on the alt.free passwords newsgroup, that information has escaped: whether or not someone has (yet) used those credentials to create mischief, your account has still been compromised. Publishing a reference poses the same sort of risk.<br />
<br />
>A final mechanism by which an object or its internal state can be published is to publish an inner class instance, as shown in ThisEscape in Listing 3.7. When ThisEscape publishes the EventListener, it implicitly publishes the enclosing ThisEscape instance as well, because inner class instances contain a hidden reference to the enclosing instance.<br />
<br />
28 Java Concurrency In Practice<br />
Listing 3.7. Implicitly Allowing the this Reference to Escape. Don't Do this.<br />
public class ThisEscape {<br />
public ThisEscape(EventSource source) {<br />
source.registerListener(<br />
new EventListener() {<br />
public void onEvent(Event e) {<br />
doSomething(e);<br />
}<br />
});<br />
}<br />
}<br />
<br />
>an object is in a predictable, consistent state only after its constructor returns, so publishing an object from within its constructor can publish an incompletely constructed object. This is true even if the publication is the last statement in the constructor. If the this reference escapes during construction, the object is considered not properly constructed.[8]<br />
[8] More specifically, the this reference should not escape from the thread until after the constructor returns. The this reference can be stored somewhere by the constructor as long as it is not used by another thread until after construction. SafeListener in Listing 3.8 uses this technique. Do not allow the this reference to escape during construction.<br />
<br />
>Calling an overrideable instance method (one that is neither private nor final) from the constructor can also allow the this reference to escape. If you are tempted to register an event listener or start a thread from a constructor, you can avoid the improper construction by using a private constructor and a public factory method, as shown in SafeListener in Listing 3.8.<br />
<br />
Listing 3.8. Using a Factory Method to Prevent the this Reference from Escaping During Construction.<br />
<br />
public class SafeListener {<br />
private final EventListener listener;<br />
private SafeListener() {<br />
listener = new EventListener() {<br />
public void onEvent(Event e) {<br />
doSomething(e);<br />
}<br />
};<br />
}<br />
<br />
public static SafeListener newInstance(EventSource source) {<br />
SafeListener safe = new SafeListener();<br />
source.registerListener(safe.listener);<br />
return safe;<br />
}<br />
}<br />
<br />
>3.3. Thread Confinement<br />
Accessing shared, mutable data requires using synchronization; one way to avoid this requirement is to not share. If data is only accessed from a single thread, no synchronization is needed. This technique, thread confinement, is one of the simplest ways to achieve thread safety. When an object is confined to a thread, such usage is automatically thread safe even if the confined object itself is not [CPJ 2.3.2].<br />
Swing uses thread confinement extensively. The Swing visual components and data model objects are not thread safe;<br />
instead, safety is achieved by confining them to the Swing event dispatch thread. To use Swing properly, code running in threads other than the event thread should not access these objects. (To make this easier, Swing provides the invokeLater mechanism to schedule a Runnable for execution in the event thread.) Many concurrency errors in Swing applications stem from improper use of these confined objects from another thread.<br />
Another common application of thread confinement is the use of pooled JDBC (Java Database Connectivity) Connection<br />
objects. The JDBC specification does not require that Connection objects be thread safe.[9] In typical server applications, a thread acquires a connection from the pool, uses it for processing a single request, and returns it. Since most requests, such as servlet requests or EJB (Enterprise JavaBeans) calls, are processed synchronously by a single thread, and the pool will not dispense the same connection to another thread until it has been returned, this pattern of connection management implicitly confines the Connection to that thread for the duration of the request.<br />
[9] The connection pool implementations provided by application servers are thread safe; connection pools are necessarily accessed from multiple threads, so a non thread safe implementation would not make sense.<br />
Just as the language has no mechanism for enforcing that a variable is guarded by a lock, it has no means of confining an object to a thread. Thread confinement is an element of your program's design that must be enforced by its implementation. The language and core libraries provide mechanisms that can help in maintaining thread confinement local variables and the ThreadLocal class but even with these, it is still the programmer's responsibility to ensure that thread confined objects do not escape from their intended thread.<br />
<br />
Stack Confinement<br />
-----------------<br />
>a special case of thread confinement<br />
>an object can only be reached through local variables - this is called stack confinement<br />
>also for primitives, the language semantics ensure that primitive local variables are always stack confined<br />
>stack confinement however resides in the heads of the programmers and hence has to be documented for the future maintainers not to let the stack local objects be published outside<br />
<br />
ThreadLocal<br />
-----------<br />
>wrap global variables in ThreadLocal object(static private field) to confine it within a thread<br />
>ThreadLocal maintains an internal map for each thread and serves the request according to the calling thread(that is current thread)<br />
<br />
Listing 3.10. Using ThreadLocal to Ensure thread Confinement.<br />
private static ThreadLocal<connection> connectionHolder</connection><br />
= new ThreadLocal<connection>() {</connection><br />
public Connection initialValue() {<br />
return DriverManager.getConnection(DB_URL);<br />
}<br />
};<br />
public static Connection getConnection() {<br />
return connectionHolder.get();<br />
}<br />
<br />
>when the thread exits, the thread local copies specific to the thread become avaialable for garbage collection<br />
<br />
Immutability<br />
------------<br />
>Immutable objects are always thread safe<br />
<br />
>[16] While it may seem that field values set in a constructor are the first values written to those fields and therefore that there are no "older" values to see as stale values, the Object constructor first writes the default values to all fields before subclass constructors run. It is therefore<br />
possible to see the default value for a field as a stale value.<br />
<br />
>Using a static initializer is often the easiest and safest way to publish objects that can be statically constructed:<br />
public static Holder holder = new Holder(42);<br />
<br />
Static initializers are executed by the JVM at class initialization time; because of internal synchronization in the JVM, this mechanism is guaranteed to safely publish any objects initialized in this way [JLS 12.4.2].<br />
<br />
>4.1. Designing a Thread safe Class<br />
<br />
The design process for a thread safe class should include these three basic elements:<br />
Identify the variables that form the object's state;<br />
Identify the invariants that constrain the state variables;<br />
Establish a policy for managing concurrent access to the object's state.<br />
<br />
>Encapsulating data within an object confines access to the data to the object's methods, making it easier to ensure that the data is always accessed with the appropriate lock held.<br />
<br />
>Confinement makes it easier to build thread safe classes because a class that confines its state can be analyzed for thread safety without having to examine the whole program.<br />
<br />
>Priority inheritance is when a thread gets a temporary bump in priority, due to what threads are waiting on locks that it owns. With priority inheritence, if a low priority thread owns a lock, that a high priority thread later wants -- it will be bumped to the higher priority. The reason is... the higher priority thread is blocked waiting for this lock, so the low priority thread needs to run at a higher priority in order to finish up and free the lock for the high priority thread. The low priority thread is "inheriting" the high priority of the high priority thread.<br />
<br />
>If a class is composed of multiple independent thread safe state variables and has no operations that have any invalid state transitions, then it can delegate thread safety to the underlying state variables.<br />
<br />
>If a state variable is thread safe, does not participate in any invariants that constrain its value, and has no prohibited state transitions for any of its operations, then it can safely be published.<br />
<br />
>If extending a class to add another atomic operation is fragile because it distributes the locking code for a class over multiple classes in an object hierarchy, client side locking is even more fragile because it entails putting locking code for class C into classes that are totally unrelated to C. Exercise care when using client side locking on classes that do not commit to their locking strategy. Client side locking has a lot in common with class extension they both couple the behavior of the derived class to the implementation of the base class. Just as extension violates encapsulation of implementation [EJ Item 14], client side locking violates encapsulation of synchronization policy.<br />
<br />
>Document a class's thread safety guarantees for its clients; document its synchronization policy for its maintainers.<br />
<br />
>Because the synchronized collections commit to a synchronization policy that supports client side locking, [1] it is possible to create new operations that are atomic with respect to other collection operations as long as we know which lock to use. The synchronized collection classes guard each method with the lock on the synchronized collection object itself.<br />
<br />
>Listing 5.3. Iteration that may Throw ArrayIndexOutOfBoundsException.<br />
for (int i = 0; i < vector.size(); i++)<br />
doSomething(vector.get(i));<br />
<br />
>using iterators does not obviate the need to lock the collection during iteration if other threads can concurrently modify it. The iterators returned by the synchronized collections are not designed to deal with concurrent modification, and they are fail fast meaning that if they detect that the collection has changed since iteration began, they throw the unchecked ConcurrentModificationException.<br />
<br />
>These fail fast iterators are not designed to be foolproof they are designed to catch concurrency errors on a "good faith effort" basis and thus act only as early warning indicators for concurrency problems. They are implemented by associating a modification count with the collection: if the modification count changes during iteration, hasNext or next throws ConcurrentModificationException. However, this check is done without synchronization, so there is a risk of seeing a stale value of the modification count and therefore that the iterator does not realize a modification has been made. This was a deliberate design tradeoff to reduce the performance impact of the concurrent modification detection code.[2]<br />
<br />
>[2] ConcurrentModificationException can arise in single threaded code as well; this happens when objects are removed from the collection directly rather than through Iterator.remove()<br />
<br />
>for-each loop also internally uses iterators to iterate the collection and hence for-each loop also can throw ConcurrentModificationException if not guarded by a lock<br />
<br />
>but locking the whole iteration loop also hurts performance(with starvation and deadlock risk as well)<br />
<br />
>possibly, the collection can be cloned in each thread for iteration(cloning itself should be guarded) if it is less costlier than concurrently iterating the same collection via multiple threads<br />
<br />
>hidden iterator is possible when we print a collection variable; internally toString() method iterates over the elements and there is a possible ConcurrentModificationException while printing a collection as well<br />
<br />
>If HiddenIterator wrapped the HashSet with a synchronizedSet, encapsulating the synchronization, this sort of error would not occur. Just as encapsulating an object's state makes it easier to preserve its invariants, encapsulating its synchronization makes it easier to enforce its synchronization policy.<br />
<br />
>Replacing synchronized collections with concurrent collections can offer dramatic scalability improvements with little risk.<br />
<br />
>While you can simulate the behavior of a Queue with a List in fact, LinkedList also implements Queue the Queue classes were added because eliminating the random access requirements of List admits more efficient concurrent implementations.<br />
<br />
>Concurrent collections, e.g. ConcurrentHashMap: Instead of synchronizing every method on a common lock, restricting access to a single thread at a time, it uses a fine grained locking mechanism called lock striping (see Section 11.4.3) to allow a greater degree of shared access.<br />
<br />
>Tradeoff with concurrent collections: iterator is not absolute; it doesn't give snapshot view of the collection; parallel modifications while iterating is allowed; size() and isEmpty() methods only tell approximate condition at that time which can change every instant; basically the absoluteness(determinability) we had with synchronized collections is lost in concurrent collections<br />
<br />
>Only if your application needs to lock the map for exclusive access [3] is ConcurrentHashMap not an appropriate drop in replacement.<br />
<br />
>Since a ConcurrentHashMap cannot be locked for exclusive access, we cannot use client side locking to create new atomic operations such as put if absent; but these are already provided in concurrent collections<br />
<br />
>CopyOnWriteArrayList/CopyOnWriteArraySet: create new collection whenever it is modified;<br />
>Iterators for the copy on write collections retain a reference to the backing array that was current at the start of iteration, and since this will never change, they need to synchronize only briefly to ensure visibility of the array contents. As a result, multiple threads can iterate the collection without interference from one another or from threads wanting to modify the collection. The iterators returned by the copy on write collections do not throw ConcurrentModificationException and return the elements exactly as they were at the time the iterator was created, regardless of subsequent modifications.<br />
<br />
>Obviously, there is some cost to copying the backing array every time the collection is modified, especially if the collection is large; the copy on write collections are reasonable to use only when iteration is far more common than modification. This criterion exactly describes many event notification systems: delivering a notification requires iterating the list of registered listeners and calling each one of them, and in most cases registering or unregistering an event listener is far less common than receiving an event notification.<br />
<br />
>BlockingQueue simplifies the implementation of producer consumer designs with any<br />
number of producers and consumers. One of the most common producer consumer designs is a thread pool coupled<br />
with a work queue; this pattern is embodied in the Executor task execution framework<br />
<br />
>If the producers consistently generate work faster than the consumers can process it, eventually the application will run out of memory because work items will queue up without bound. Again, the blocking nature of put greatly simplifies coding of producers; if we use a bounded queue, then when the queue fills up the producers block, giving the consumers time to catch up because a blocked producer cannot generate more work.<br />
<br />
>Bounded queues are a powerful resource management tool for building reliable applications: they make your program<br />
more robust to overload by throttling activities that threaten to produce more work than can be handled.<br />
<br />
>if blocking queues don't fit easily into your design, you can create other blocking data structures using Semaphore<br />
<br />
>The last BlockingQueue implementation, SynchronousQueue, is not really a queue at all, in that it maintains no storage<br />
space for queued elements. Instead, it maintains a list of queued threads waiting to enqueue or dequeue an element. In<br />
the dish washing analogy, this would be like having no dish rack, but instead handing the washed dishes directly to the next available dryer. While this may seem a strange way to implement a queue, it reduces the latency associated with moving data from producer to consumer because the work can be handed off directly. (In a traditional queue, the enqueue and dequeue operations must complete sequentially before a unit of work can be handed off.) The direct handoff also feeds back more information about the state of the task to the producer; when the handoff is accepted, it knows a consumer has taken responsibility for it, rather than simply letting it sit on a queue somewhere much like the difference between handing a document to a colleague and merely putting it in her mailbox and hoping she gets it soon.<br />
Since a SynchronousQueue has no storage capacity, put and take will block unless another thread is already waiting to<br />
participate in the handoff. Synchronous queues are generally suitable only when there are enough consumers that there<br />
nearly always will be one ready to take the handoff.<br />
<br />
>The producer consumer pattern also enables several performance benefits. Producers and consumers can execute concurrently; if one is I/O bound and the other is CPU bound, executing them concurrently yields better overall throughput than executing them sequentially.<br />
<br />
>5.3.2. Serial Thread Confinement<br />
The blocking queue implementations in java.util.concurrent all contain sufficient internal synchronization to safely<br />
publish objects from a producer thread to the consumer thread.<br />
<br />
For mutable objects, producer consumer designs and blocking queues facilitate serial thread confinement for handing<br />
off ownership of objects from producers to consumers. A thread confined object is owned exclusively by a single thread, but that ownership can be "transferred" by publishing it safely where only one other thread will gain access to it and ensuring that the publishing thread does not access it after the handoff. The safe publication ensures that the object's state is visible to the new owner, and since the original owner will not touch it again, it is now confined to the new thread. The new owner may modify it freely since it has exclusive access.<br />
Object pools exploit serial thread confinement, "lending" an object to a requesting thread. As long as the pool contains sufficient internal synchronization to publish the pooled object safely, and as long as the clients do not themselves publish the pooled object or use it after returning it to the pool, ownership can be transferred safely from thread to thread.<br />
One could also use other publication mechanisms for transferring ownership of a mutable object, but it is necessary to<br />
ensure that only one thread receives the object being handed off. Blocking queues make this easy; with a little more work, it could also be done with the atomic remove method of ConcurrentMap or the compareAndSet method of AtomicReference.<br />
<br />
>5.3.3. Deques and Work Stealing<br />
Java 6 also adds another two collection types, Deque (pronounced "deck") and BlockingDeque, that extend Queue and<br />
BlockingQueue. A Deque is a double ended queue that allows efficient insertion and removal from both the head and<br />
the tail. Implementations include ArrayDeque and LinkedBlockingDeque.<br />
Just as blocking queues lend themselves to the producer consumer pattern, deques lend themselves to a related pattern called work stealing. A producer consumer design has one shared work queue for all consumers; in a work stealing design, every consumer has its own deque. If a consumer exhausts the work in its own deque, it can steal work from the tail of someone else's deque. Work stealing can be more scalable than a traditional producer consumer design because workers don't contend for a shared work queue; most of the time they access only their own deque, reducing contention. When a worker has to access another's queue, it does so from the tail rather than the head, further reducing contention.<br />
Work stealing is well suited to problems in which consumers are also producers when performing a unit of work is likely to result in the identification of more work. For example, processing a page in a web crawler usually results in the identification of new pages to be crawled. Similarly, many graph exploring algorithms, such as marking the heap during garbage collection, can be efficiently parallelized using work stealing. When a worker identifies a new unit of work, it places it at the end of its own deque (or alternatively, in a work sharing design, on that of another worker); when its deque is empty, it looks for work at the end of someone else's deque, ensuring that each worker stays busy.<br />
<br />
>The put and take methods of BlockingQueue throw the checked InterruptedException, as do a number of other library methods such as Thread.sleep. When a method can throw InterruptedException, it is telling you that it is a blocking method, and further that if it is interrupted, it will make an effort to stop blocking early.<br />
<br />
Interruption is a cooperative mechanism. One thread cannot force another to stop what it is doing and do something<br />
else; when thread A interrupts thread B, A is merely requesting that B stop what it is doing when it gets to a convenient stopping point if it feels like it. While there is nothing in the API or language specification that demands any specific application level semantics for interruption, the most sensible use for interruption is to cancel an activity. Blocking methods that are responsive to interruption make it easier to cancel long running activities on a timely basis.<br />
<br />
>When your code calls a method that throws InterruptedException, then your method is a blocking method too, and<br />
must have a plan for responding to interruption. For library code, there are basically two choices:<br />
Propagate the InterruptedException. This is often the most sensible policy if you can get away with it just propagate<br />
the InterruptedException to your caller. This could involve not catching InterruptedException, or catching it and<br />
throwing it again after performing some brief activity specific cleanup.<br />
Restore the interrupt. Sometimes you cannot throw InterruptedException, for instance when your code is part of a<br />
Runnable. In these situations, you must catch InterruptedException and restore the interrupted status by calling<br />
interrupt on the current thread, so that code higher up the call stack can see that an interrupt was issued, as<br />
demonstrated in Listing 5.10.<br />
You can get much more sophisticated with interruption, but these two approaches should work in the vast majority of<br />
situations. But there is one thing you should not do with InterruptedException; catch it and do nothing in response.<br />
This deprives code higher up on the call stack of the opportunity to act on the interruption, because the evidence that<br />
the thread was interrupted is lost. The only situation in which it is acceptable to swallow an interrupt is when you are<br />
extending Thread and therefore control all the code higher up on the call stack.<br />
<br />
Listing 5.10. Restoring the Interrupted Status so as Not to Swallow the Interrupt.<br />
public class TaskRunnable implements Runnable {<br />
BlockingQueue<task> queue;</task><br />
...<br />
public void run() {<br />
try {<br />
processTask(queue.take());<br />
} catch (InterruptedException e) {<br />
// restore interrupted status<br />
Thread.currentThread().interrupt();<br />
}<br />
}<br />
}<br />
<br />
>5.5. Synchronizers<br />
Blocking queues are unique among the collections classes: not only do they act as containers for objects, but they can<br />
also coordinate the control flow of producer and consumer threads because take and put block until the queue enters<br />
the desired state (not empty or not full).<br />
A synchronizer is any object that coordinates the control flow of threads based on its state. Blocking queues can act as<br />
synchronizers; other types of synchronizers include semaphores, barriers, and latches. There are a number of<br />
synchronizer classes in the platform library; if these do not meet your needs, you can also create your own<br />
<br />
>Latches - one time use synchronizers; latch is closed(blocks all threads) until a given condition happens; after the condition occurs, the latch is opened permanently(all threads can pass the gate)<br />
>CountDownLatch - blocks all threads until a given counter reaches zero(can be initialized to a positive value upon start)<br />
>in a thread pool, the master thread can wait at once for all workers to finish using a countdown latch instead of waiting on each one sequentially; also the master can start all threads at once using a latch<br />
<br />
Ensuring that a computation does not proceed until resources it needs have been initialized. A simple binary<br />
(two state) latch could be used to indicate "Resource R has been initialized", and any activity that requires R<br />
would wait first on this latch.<br />
Ensuring that a service does not start until other services on which it depends have started. Each service would<br />
have an associated binary latch; starting service S would involve first waiting on the latches for other services on<br />
which S depends, and then releasing the S latch after startup completes so any services that depend on S can<br />
then proceed.<br />
Waiting until all the parties involved in an activity, for instance the players in a multi player game, are ready to<br />
proceed. In this case, the latch reaches the terminal state after all the players are ready.<br />
<br />
>FutureTask also acts like a latch<br />
<br />
Ensuring that a computation does not proceed until resources it needs have been initialized. A simple binary<br />
(two state) latch could be used to indicate "Resource R has been initialized", and any activity that requires R<br />
would wait first on this latch.<br />
Ensuring that a service does not start until other services on which it depends have started. Each service would<br />
have an associated binary latch; starting service S would involve first waiting on the latches for other services on<br />
which S depends, and then releasing the S latch after startup completes so any services that depend on S can<br />
then proceed.<br />
Waiting until all the parties involved in an activity, for instance the players in a multi player game, are ready to<br />
proceed. In this case, the latch reaches the terminal state after all the players are ready.<br />
<br />
Tasks described by Callable can throw checked and unchecked exceptions, and any code can throw an Error.<br />
Whatever the task code may throw, it is wrapped in an ExecutionException and rethrown from Future.get. This<br />
complicates code that calls get, not only because it must deal with the possibility of ExecutionException (and the<br />
unchecked CancellationException), but also because the cause of the ExecutionException is returned as a<br />
THRowable, which is inconvenient to deal with.<br />
<br />
5.5.3. Semaphores<br />
Counting semaphores are used to control the number of activities that can access a certain resource or perform a given<br />
action at the same time [CPJ 3.4.1]. Counting semaphores can be used to implement resource pools or to impose a<br />
bound on a collection.<br />
A Semaphore manages a set of virtual permits; the initial number of permits is passed to the Semaphore constructor.<br />
Activities can acquire permits (as long as some remain) and release permits when they are done with them. If no permit<br />
is available, acquire blocks until one is (or until interrupted or the operation times out). The release method returns a<br />
permit to the semaphore. [4] A degenerate case of a counting semaphore is a binary semaphore, a Semaphore with an<br />
initial count of one. A binary semaphore can be used as a mutex with non reentrant locking semantics; whoever holds<br />
the sole permit holds the mutex.<br />
<br />
[4] The implementation has no actual permit objects, and Semaphore does not associate dispensed permits with threads, so a permit acquired in<br />
one thread can be released from another thread. You can think of acquire as consuming a permit and release as creating one; a Semaphore is not<br />
limited to the number of permits it was created with.<br />
Semaphores are useful for implementing resource pools such as database connection pools. While it is easy to construct<br />
a fixed sized pool that fails if you request a resource from an empty pool, what you really want is to block if the pool is<br />
empty and unblock when it becomes nonempty again. If you initialize a Semaphore to the pool size, acquire a permit<br />
before trying to fetch a resource from the pool, and release the permit after putting a resource back in the pool,<br />
acquire blocks until the pool becomes nonempty. This technique is used in the bounded buffer class in Chapter 12. (An<br />
easier way to construct a blocking object pool would be to use a BlockingQueue to hold the pooled resources.)<br />
Similarly, you can use a Semaphore to turn any collection into a blocking bounded collection, as illustrated by<br />
BoundedHashSet in Listing 5.14. The semaphore is initialized to the desired maximum size of the collection. The add<br />
operation acquires a permit before adding the item into the underlying collection. If the underlying add operation does<br />
not actually add anything, it releases the permit immediately. Similarly, a successful remove operation releases a permit,<br />
enabling more elements to be added. The underlying Set implementation knows nothing about the bound; this is<br />
handled by BoundedHashSet.<br />
<br />
5.5.4. Barriers<br />
We have seen how latches can facilitate starting a group of related activities or waiting for a group of related activities<br />
to complete. Latches are single use objects; once a latch enters the terminal state, it cannot be reset.<br />
Barriers are similar to latches in that they block a group of threads until some event has occurred [CPJ 4.4.3]. The key<br />
difference is that with a barrier, all the threads must come together at a barrier point at the same time in order to<br />
proceed. Latches are for waiting for events; barriers are for waiting for other threads. A barrier implements the protocol<br />
some families use to rendezvous during a day at the mall: "Everyone meet at McDonald's at 6:00; once you get there,<br />
stay there until everyone shows up, and then we'll figure out what we're doing next."<br />
CyclicBarrier allows a fixed number of parties to rendezvous repeatedly at a barrier point and is useful in parallel<br />
iterative algorithms that break down a problem into a fixed number of independent subproblems. Threads call await<br />
when they reach the barrier point, and await blocks until all the threads have reached the barrier point. If all threads<br />
meet at the barrier point, the barrier has been successfully passed, in which case all threads are released and the barrier<br />
is reset so it can be used again. If a call to await times out or a thread blocked in await is interrupted, then the barrier is<br />
considered broken and all outstanding calls to await terminate with BrokenBarrierException. If the barrier is<br />
successfully passed, await returns a unique arrival index for each thread, which can be used to "elect" a leader that<br />
takes some special action in the next iteration. CyclicBarrier also lets you pass a barrier action to the constructor;<br />
this is a Runnable that is executed (in one of the subtask threads) when the barrier is successfully passed but before the<br />
blocked threads are released.<br />
<br />
Another form of barrier is Exchanger, a two party barrier in which the parties exchange data at the barrier point [CPJ<br />
3.4.3]. Exchangers are useful when the parties perform asymmetric activities, for example when one thread fills a buffer<br />
with data and the other thread consumes the data from the buffer; these threads could use an Exchanger to meet and<br />
exchange a full buffer for an empty one. When two threads exchange objects via an Exchanger, the exchange<br />
constitutes a safe publication of both objects to the other party.<br />
The timing of the exchange depends on the responsiveness requirements of the application. The simplest approach is<br />
that the filling task exchanges when the buffer is full, and the emptying task exchanges when the buffer is empty; this<br />
minimizes the number of exchanges but can delay processing of some data if the arrival rate of new data is<br />
unpredictable. Another approach would be that the filler exchanges when the buffer is full, but also when the buffer is<br />
partially filled and a certain amount of time has elapsed.<br />
<br />
>JVM can't exit until all the (non daemon) threads have terminated, so failing to<br />
shut down an Executor could prevent the JVM from exiting.<br />
<br />
>6.2.5. Delayed and Periodic Tasks<br />
The Timer facility manages the execution of deferred ("run this task in 100 ms") and periodic ("run this task every 10<br />
ms") tasks. However, Timer has some drawbacks, and ScheduledThreadPoolExecutor should be thought of as its<br />
replacement.[6] You can construct a ScheduledThreadPoolExecutor through its constructor or through the<br />
newScheduledThreadPool factory.<br />
<br />
78 Java Concurrency In Practice<br />
[6] Timer does have support for scheduling based on absolute, not relative time, so that tasks can be sensitive to changes in the system clock;<br />
ScheduledThreadPoolExecutor supports only relative time.<br />
A Timer creates only a single thread for executing timer tasks. If a timer task takes too long to run, the timing accuracy<br />
of other TimerTasks can suffer. If a recurring TimerTask is scheduled to run every 10 ms and another Timer-Task takes<br />
40 ms to run, the recurring task either (depending on whether it was scheduled at fixed rate or fixed delay) gets called<br />
four times in rapid succession after the long running task completes, or "misses" four invocations completely. Scheduled<br />
thread pools address this limitation by letting you provide multiple threads for executing deferred and periodic tasks.<br />
Another problem with Timer is that it behaves poorly if a TimerTask throws an unchecked exception. The Timer thread<br />
doesn't catch the exception, so an unchecked exception thrown from a TimerTask terminates the timer thread. Timer<br />
also doesn't resurrect the thread in this situation; instead, it erroneously assumes the entire Timer was cancelled. In this<br />
case, TimerTasks that are already scheduled but not yet executed are never run, and new tasks cannot be scheduled.<br />
(This problem, called "thread leakage" is described in Section 7.3, along with techniques for avoiding it.)<br />
<br />
>ScheduledThreadPoolExecutor deals<br />
properly with ill behaved tasks; there is little reason to use Timer in Java 5.0 or later.<br />
If you need to build your own scheduling service, you may still be able to take advantage of the library by using a<br />
DelayQueue, a BlockingQueue implementation that provides the scheduling functionality of<br />
ScheduledThreadPoolExecutor. A DelayQueue manages a collection of Delayed objects. A Delayed has a delay time<br />
associated with it: DelayQueue lets you take an element only if its delay has expired. Objects are returned from a<br />
DelayQueue ordered by the time associated with their delay.<br />
<br />
>Future represents the lifecycle of a task and provides methods to test whether the task has completed or been<br />
cancelled, retrieve its result, and cancel the task. Callable and Future are shown in Listing 6.11. Implicit in the<br />
specification of Future is that task lifecycle can only move forwards, not backwards just like the ExecutorService<br />
lifecycle. Once a task is completed, it stays in that state forever.<br />
The behavior of get varies depending on the task state (not yet started, running, completed). It returns immediately or<br />
throws an Exception if the task has already completed, but if not it blocks until the task completes. If the task<br />
completes by throwing an exception, get rethrows it wrapped in an ExecutionException; if it was cancelled, get<br />
throws CancellationException. If get throws ExecutionException, the underlying exception can be retrieved with<br />
getCause.<br />
<br />
>There are several ways to create a Future to describe a task. The submit methods in ExecutorService all return a<br />
Future, so that you can submit a Runnable or a Callable to an executor and get back a Future that can be used to<br />
retrieve the result or cancel the task. You can also explicitly instantiate a FutureTask for a given Runnable or Callable.<br />
(Because FutureTask implements Runnable, it can be submitted to an Executor for execution or executed directly by<br />
calling its run method.)<br />
<br />
As of Java 6, ExecutorService implementations can override newTaskFor in AbstractExecutorService to control<br />
instantiation of the Future corresponding to a submitted Callable or Runnable. The default implementation just<br />
creates a new FutureTask, as shown in Listing 6.12.<br />
Listing 6.12. Default Implementation of newTaskFor in ThreadPoolExecutor.<br />
protected <t> RunnableFuture<t> newTaskFor(Callable<t> task) {</t></t></t><br />
return new FutureTask<t>(task);</t><br />
}<br />
<br />
Submitting a Runnable or Callable to an Executor constitutes a safe publication (see Section 3.5) of the Runnable or<br />
Callable from the submitting thread to the thread that will eventually execute the task. Similarly, setting the result<br />
value for a Future constitutes a safe publication of the result from the thread in which it was computed to any thread<br />
that retrieves it via get.<br />
<br />
>The primary challenge in executing tasks within a time budget is making sure that you don't wait longer than the time<br />
budget to get an answer or find out that one is not forthcoming. The timed version of Future.get supports this<br />
requirement: it returns as soon as the result is ready, but throws TimeoutException if the result is not ready within the<br />
timeout period.<br />
<br />
Cancelling a task<br />
-----------------<br />
>One such cooperative mechanism is setting a "cancellation requested" flag that the task checks periodically; if it finds<br />
the flag set, the task terminates early. PrimeGenerator in Listing 7.1, which enumerates prime numbers until it is<br />
cancelled, illustrates this technique. The cancel method sets the cancelled flag, and the main loop polls this flag<br />
before searching for the next prime number. (For this to work reliably, cancelled must be volatile.)<br />
<br />
>Blocking library methods like Thread.sleep and Object.wait try to detect when a thread has been interrupted and<br />
return early. They respond to interruption by clearing the interrupted status and throwing InterruptedException,<br />
indicating that the blocking operation completed early due to interruption. The JVM makes no guarantees on how<br />
quickly a blocking method will detect interruption, but in practice this happens reasonably quickly.<br />
<br />
>If a thread is interrupted when it is not blocked, its interrupted status is set, and it is up to the activity being cancelled to<br />
poll the interrupted status to detect interruption. In this way interruption is "sticky?” if it doesn't trigger an<br />
InterruptedException, evidence of interruption persists until someone deliberately clears the interrupted status.<br />
Calling interrupt does not necessarily stop the target thread from doing what it is doing; it merely delivers the<br />
message that interruption has been requested.<br />
A good way to think about interruption is that it does not actually interrupt a running thread; it just requests that the<br />
thread interrupt itself at the next convenient opportunity. (These opportunities are called cancellation points.) Some<br />
methods, such as wait, sleep, and join, take such requests seriously, throwing an exception when they receive an<br />
interrupt request or encounter an already set interrupt status upon entry. Well behaved methods may totally ignore<br />
such requests so long as they leave the interruption request in place so that calling code can do something with it.<br />
Poorly behaved methods swallow the interrupt request, thus denying code further up the call stack the opportunity to<br />
act on it.<br />
The static interrupted method should be used with caution, because it clears the current thread's interrupted status. If<br />
you call interrupted and it returns TRue, unless you are planning to swallow the interruption, you should do something<br />
with it either throw InterruptedException or restore the interrupted status by calling interrupt again<br />
<br />
>Interruption is usually the most sensible way to implement cancellation.<br />
<br />
>Because each thread has its own interruption policy, you should not interrupt a thread unless you know what<br />
interruption means to that thread.<br />
Critics have derided the Java interruption facility because it does not provide a preemptive interruption capability and<br />
yet forces developers to handle InterruptedException. However, the ability to postpone an interruption request<br />
enables developers to craft flexible interruption policies that balance responsiveness and robustness as appropriate for<br />
the application.<br />
<br />
>Only code that implements a thread's interruption policy may swallow an interruption request. General purpose task<br />
and library code should never swallow interruption requests.<br />
<br />
GUI APPLICATIONS<br />
-----------------<br />
>Single threaded GUI frameworks are not unique to Java; Qt, NextStep, MacOS Cocoa, X Windows, and many others are<br />
also single threaded. This is not for lack of trying; there have been many attempts to write multithreaded GUI<br />
frameworks, but because of persistent problems with race conditions and deadlock, they all eventually arrived at the<br />
single threaded event queue model in which a dedicated thread fetches events off a queue and dispatches them to<br />
application defined event handlers. (AWT originally tried to support a greater degree of multithreaded access, and the<br />
decision to make Swing single threaded was based largely on experience with AWT.)<br />
<br />
>Multithreaded GUI frameworks tend to be particularly susceptible to deadlock, partially because of the unfortunate<br />
interaction between input event processing and any sensible object oriented modeling of GUI components. Actions<br />
initiated by the user tend to "bubble up" from the OS to the application a mouse click is detected by the OS, is turned<br />
into a "mouse click" event by the toolkit, and is eventually delivered to an application listener as a higher level event<br />
such as a "button pressed" event. On the other hand, application initiated actions "bubble down" from the application<br />
to the OS changing the background color of a component originates in the application and is dispatched to a specific<br />
component class and eventually into the OS for rendering. Combining this tendency for activities to access the same GUI<br />
objects in the opposite order with the requirement of making each object thread safe yields a recipe for inconsistent<br />
lock ordering, which leads to deadlock (see Chapter 10). And this is exactly what nearly every GUI toolkit development<br />
effort rediscovered through experience.<br />
<br />
>Another factor leading to deadlock in multithreaded GUI frameworks is the prevalence of the model view control (MVC)<br />
pattern. Factoring user interactions into cooperating model, view, and controller objects greatly simplifies implementing<br />
GUI applications, but again raises the risk of inconsistent lock ordering. The controller calls into the model, which<br />
notifies the view that something has changed. But the controller can also call into the view, which may in turn call back<br />
into the model to query the model state. The result is again inconsistent lock ordering, with the attendant risk of<br />
deadlock.<br />
In his weblog,[1] Sun VP Graham Hamilton nicely sums up the challenges, describing why the multithreaded GUI toolkit is<br />
one of the recurring "failed dreams" of computer science.<br />
[1] http://weblogs.java.net/blog/kgh/archive/2004/10<br />
<br />
>if you were to use multithreaded UI toolkits, things will mostly<br />
work, but you will get occasional hangs (due to deadlocks) or glitches (due to races). This multithreaded approach works<br />
best for people who have been intimately involved in the design of the toolkit.<br />
<br />
>Single threaded GUI frameworks achieve thread safety via thread confinement; all GUI objects, including visual<br />
components and data models, are accessed exclusively from the event thread. Of course, this just pushes some of the<br />
thread safety burden back onto the application developer, who must make sure these objects are properly confined.<br />
<br />
>9.1.2. Thread Confinement in Swing<br />
All Swing components (such as JButton and JTable) and data model objects (such as TableModel and TreeModel) are<br />
confined to the event thread, so any code that accesses these objects must run in the event thread. GUI objects are kept<br />
consistent not by synchronization, but by thread confinement. The upside is that tasks that run in the event thread need<br />
not worry about synchronization when accessing presentation objects; the downside is that you cannot access<br />
presentation objects from outside the event thread at all.<br />
<br />
>The Swing single thread rule: Swing components and models should be created, modified, and queried only from the<br />
event dispatching thread.<br />
<br />
>As with all rules, there are a few exceptions. A small number of Swing methods may be called safely from any thread;<br />
these are clearly identified in the Javadoc as being thread safe. Other exceptions to the single thread rule include:<br />
SwingUtilities.isEventDispatchThread, which determines whether the current thread is the event thread;<br />
SwingUtilities.invokeLater, which schedules a Runnable for execution on the event thread (callable from<br />
any thread);<br />
SwingUtilities.invokeAndWait, which schedules a Runnable task for execution on the event thread and<br />
blocks the current thread until it completes (callable only from a non GUI thread);<br />
methods to enqueue a repaint or revalidation request on the event queue (callable from any thread); and<br />
methods for adding and removing listeners (can be called from any thread, but listeners will always be invoked<br />
in the event thread).<br />
<br />
>In a GUI application, events originate in the event thread and bubble up to application provided listeners, which will<br />
probably perform some computation that affects the presentation objects. For simple, short running tasks, the entire<br />
action can stay in the event thread; for longer running tasks, some of the processing should be offloaded to another<br />
thread.<br />
<br />
>In the simple case, confining presentation objects to the event thread is completely natural. Listing 9.3 creates a button<br />
whose color changes randomly when pressed. When the user clicks on the button, the toolkit delivers an ActionEvent<br />
in the event thread to all registered action listeners. In response, the action listener picks a new color and changes the<br />
button's background color. So the event originates in the GUI toolkit and is delivered to the application, and the<br />
application modifies the GUI in response to the user's action. Control never has to leave the event thread<br />
<br />
>When the view<br />
receives an event indicating the model data may have changed, it queries the model for the new data and updates the<br />
display. So in a button listener that modifies the contents of a table, the action listener would update the model and call<br />
one of the fireXxx methods, which would in turn invoke the view's table model listeners, which would update the<br />
view. Again, control never leaves the event thread. (The Swing data model fireXxx methods always call the model<br />
listeners directly rather than submitting a new event to the event queue, so the fireXxx methods must be called only<br />
from the event thread.)<br />
<br />
>The task triggered when the button is pressed is composed of three sequential subtasks whose execution alternates<br />
between the event thread and the background thread. The first subtask updates the user interface to show that a long<br />
running operation has begun and starts the second subtask in a background thread. Upon completion, the second<br />
subtask queues the third subtask to run again in the event thread, which updates the user interface to reflect that the<br />
operation has completed. This sort of "thread hopping" is typical of handling long running tasks in GUI applications.<br />
<br />
>9.3.1. Cancellation<br />
Any task that takes long enough to run in another thread probably also takes long enough that the user might want to<br />
cancel it. You could implement cancellation directly using thread interruption, but it is much easier to use Future, which<br />
was designed to manage cancellable tasks.<br />
When you call cancel on a Future with mayInterruptIfRunning set to true, the Future implementation interrupts<br />
the thread that is executing the task if it is currently running. If your task is written to be responsive to interruption, it<br />
can return early if it is cancelled. Listing 9.6 illustrates a task that polls the thread's interrupted status and returns early<br />
on interruption.<br />
<br />
>regardless of how thread pool is implemented it is the task that has to be coded to be responsive to interrupts if it has to be a cancellable task<br />
<br />
>SwingUtilities is there to submit tasks to EventDispatchThread(EDT)<br />
>SwingWorker is there to create cancellable, progressful tasks that can run on thirdparty threads (other than EDT)<br />
<br />
>when GUI data model has to be updated in thread-safe manner use the same thread jumping technique with SwingWorker and SwingUtilities, to post model updates to EDT so that it can update the DataModel<br />
<br />
>otherwise, EDT and background threads can use concurrent collections(such as ConcurrentHashMap, CopyOnWriteArrayList) to safely share data only when it suits the context<br />
<br />
9.4.2. Split Data Models<br />
----------------------------<br />
>From the perspective of the GUI, the Swing table model classes like TableModel and treeModel are the official<br />
repository for data to be displayed. However, these model objects are often themselves "views" of other objects<br />
managed by the application. A program that has both a presentation domain and an application domain data model is<br />
said to have a split model design (Fowler, 2005).<br />
In a split model design, the presentation model is confined to the event thread and the other model, the shared model,<br />
is thread safe and may be accessed by both the event thread and application threads. The presentation model registers<br />
listeners with the shared model so it can be notified of updates. The presentation model can then be updated from the<br />
shared model by embedding a snapshot of the relevant state in the update message or by having the presentation<br />
model retrieve the data directly from the shared model when it receives an update event.<br />
>this was the case with Brocade EFCM product which has server side model updating client side GUI via event notifications (the model in question was maintained at both the server and at the client GUI model)<br />
<br />
>The snapshot approach is simple, but has limitations. It works well when the data model is small, updates are not too<br />
frequent, and the structure of the two models are similar. If the data model is large or updates are very frequent, or if one<br />
or both sides of the split contain information that is not visible to the other side, it can be more efficient to send<br />
incremental updates instead of entire snapshots. This approach has the effect of serializing updates on the shared<br />
model and recreating them in the event thread against the presentation model. Another advantage of incremental<br />
updates is that finer grained information about what changed can improve the perceived quality of the displayif only<br />
one vehicle moves, we don't have to repaint the entire display, just the affected regions.<br />
<br />
>Consider a split model design when a data model must be shared by more than one thread and implementing a thread<br />
safe data model would be inadvisable because of blocking, consistency, or complexity reasons.<br />
<br />
>Borrowing from the approach taken by GUI frameworks, you can easily create a dedicated thread or single threaded<br />
executor for accessing the native library, and provide a proxy object that intercepts calls to the thread confined object<br />
and submits them as tasks to the dedicated thread. Future and newSingleThreadExecutor work together to make this<br />
easy; the proxy method can submit the task and immediately call Future.get to wait for the result. (If the class to be<br />
thread confined implements an interface, you can automate the process of having each method submit a Callable to a<br />
background thread executor and waiting for the result using dynamic proxies.)<br />
----x----<br />
<br />
7.3.1. Uncaught Exception Handlers<br />
----------------------------------<br />
The previous section offered a proactive approach to the problem of unchecked exceptions. The Thread API also<br />
provides the UncaughtExceptionHandler facility, which lets you detect when a thread dies due to an uncaught<br />
exception. The two approaches are complementary: taken together, they provide defense indepth against thread<br />
leakage.<br />
When a thread exits due to an uncaught exception, the JVM reports this event to an application provided<br />
UncaughtExceptionHandler (see Listing 7.24); if no handler exists, the default behavior is to print the stack trace to<br />
System.err.[8]<br />
[8] Before Java 5.0, the only way to control the UncaughtExceptionHandler was by subclassing ThreadGroup[ThreadGroup implements UncaughtExceptionHandler interface; we need access to uncaughtException(Thread, Throwable) method from there]. In Java 5.0 and later, you<br />
can set an UncaughtExceptionHandler on a per thread basis with Thread.setUncaughtExceptionHandler, and can also set the<br />
default UncaughtExceptionHandler with Thread.setDefaultUncaughtExceptionHandler. However, only one of these<br />
handlers is called; first JVM looks for a per thread handler, then for a ThreadGroup handler. The default handler implementation in<br />
ThreadGroup delegates to its parent thread group, and so on up the chain until one of the ThreadGroup handlers deals with the uncaught<br />
exception or it bubbles up to the toplevel thread group. The top level thread group handler delegates to the default system handler (if one exists;<br />
the default is none) and otherwise prints the stack trace to the console.<br />
Listing 7.24. UncaughtExceptionHandler Interface.<br />
public interface UncaughtExceptionHandler {<br />
void uncaughtException(Thread t, Throwable e);<br />
}<br />
What the handler should do with an uncaught exception depends on your quality of service requirements. The most<br />
common response is to write an error message and stack trace to the application log, as shown in Listing 7.25. Handlers<br />
can also take more direct action, such as trying to restart the thread, shutting down the application, paging an operator,<br />
or other corrective or diagnostic action.<br />
Listing 7.25. UncaughtExceptionHandler that Logs the Exception.<br />
public class UEHLogger implements Thread.UncaughtExceptionHandler {<br />
public void uncaughtException(Thread t, Throwable e) {<br />
Logger logger = Logger.getAnonymousLogger();<br />
logger.log(Level.SEVERE,<br />
"Thread terminated with exception: " + t.getName(),<br />
e);<br />
}<br />
}<br />
<br />
In long running applications, always use uncaught exception handlers for all threads that at least log the exception.<br />
<br />
To set an UncaughtExceptionHandler for pool threads, provide a ThreadFactory to the ThreadPoolExecutor<br />
constructor. (As with all thread manipulation, only the thread's owner should change its UncaughtExceptionHandler.)<br />
The standard thread pools allow an uncaught task exception to terminate the pool thread, but use a try-finally block<br />
to be notified when this happens so the thread can be replaced. Without an uncaught exception handler or other failure<br />
notification mechanism, tasks can appear to fail silently, which can be very confusing. If you want to be notified when a<br />
task fails due to an exception so that you can take some task specific recovery action, either wrap the task with a<br />
Runnable or Callable that catches the exception or override the afterExecute hook in ThreadPoolExecutor.<br />
Somewhat confusingly, exceptions thrown from tasks make it to the uncaught exception handler only for tasks<br />
submitted with execute; for tasks submitted with submit, any thrown exception, checked or not, is considered to be<br />
part of the task's return status. If a task submitted with submit terminates with an exception, it is rethrown by<br />
Future.get, wrapped in an ExecutionException.<br />
<br />
<br />
7.4. JVM Shutdown<br />
---------------------<br />
The JVM can shut down in either an orderly or abrupt manner. An orderly shutdown is initiated when the last "normal"<br />
(non daemon) thread terminates, someone calls System.exit, or by other platform specific means (such as sending a<br />
SIGINT or hitting Ctrl-C). While this is the standard and preferred way for the JVM to shut down, it can also be shut<br />
down abruptly by calling Runtime.halt or by killing the JVM process through the operating system (such as sending a<br />
SIGKILL).<br />
7.4.1. Shutdown Hooks<br />
In an orderly shutdown, the JVM first starts all registered shutdown hooks. Shutdown hooks are unstarted threads that<br />
are registered with Runtime.addShutdownHook. The JVM makes no guarantees on the order in which shutdown hooks<br />
are started. If any application threads (daemon or nondaemon) are still running at shutdown time, they continue to run<br />
concurrently with the shutdown process. When all shutdown hooks have completed, the JVM may choose to run<br />
finalizers if runFinalizersOnExit is true, and then halts. The JVM makes no attempt to stop or interrupt any<br />
application threads that are still running at shutdown time; they are abruptly terminated when the JVM eventually halts.<br />
If the shutdown hooks or finalizers don't complete, then the orderly shutdown process "hangs" and the JVM must be<br />
shut down abruptly. In an abrupt shutdown, the JVM is not required to do anything other than halt the JVM; shutdown<br />
hooks will not run.<br />
Shutdown hooks should be thread safe: they must use synchronization when accessing shared data and should be<br />
careful to avoid deadlock, just like any other concurrent code. Further, they should not make assumptions about the<br />
state of the application (such as whether other services have shut down already or all normal threads have completed)<br />
or about why the JVM is shutting down, and must therefore be coded extremely defensively. Finally, they should exit as<br />
quickly as possible, since their existence delays JVM termination at a time when the user may be expecting the JVM to<br />
terminate quickly.<br />
Shutdown hooks can be used for service or application cleanup, such as deleting temporary files or cleaning up<br />
resources that are not automatically cleaned up by the OS. Listing 7.26 shows how LogService in Listing 7.16 could<br />
register a shutdown hook from its start method to ensure the log file is closed on exit.<br />
Because shutdown hooks all run concurrently, closing the log file could cause trouble for other shutdown hooks who<br />
want to use the logger. To avoid this problem, shutdown hooks should not rely on services that can be shut down by the<br />
application or other shutdown hooks. One way to accomplish this is to use a single shutdown hook for all services,<br />
rather than one for each service, and have it call a series of shutdown actions. This ensures that shutdown actions<br />
execute sequentially in a single thread, thus avoiding the possibility of race conditions or deadlock between shutdown<br />
actions. This technique can be used whether or not you use shutdown hooks; executing shutdown actions sequentially<br />
rather than concurrently eliminates many potential sources of failure. In applications that maintain explicit dependency<br />
information among services, this technique can also ensure that shutdown actions are performed in the right order.<br />
<br />
Listing 7.26. Registering a Shutdown Hook to Stop the Logging Service.<br />
public void start() {<br />
Runtime.getRuntime().addShutdownHook(new Thread() {<br />
public void run() {<br />
try { LogService.this.stop(); }<br />
catch (InterruptedException ignored) {}<br />
}<br />
});<br />
}<br />
<br />
>All JVM created threads are daemon threads except for main thread<br />
<br />
>Normal threads and daemon threads differ only in what happens when they exit. When a thread exits, the JVM<br />
performs an inventory of running threads, and if the only threads that are left are daemon threads, it initiates an orderly<br />
shutdown. When the JVM halts, any remaining daemon threads are abandoned finally blocks are not executed,<br />
stacks are not unwound the JVM just exits.<br />
>but System.exit() does not wait for all user threads to finish; it just waits for shutdown hooks to finish and terminates regardless of the presence of any user or daemon threads<br />
<br />
Finalizers<br />
-----------<br />
Since finalizers can run in a thread managed by the JVM, any state accessed by a finalizer will be accessed by more than<br />
one thread and therefore must be accessed with synchronization. Finalizers offer no guarantees on when or even if they<br />
run, and they impose a significant performance cost on objects with nontrivial finalizers. They are also extremely<br />
difficult to write correctly.[9] In most cases, the combination of finally blocks and explicit close methods does a better<br />
job of resource management than finalizers; the sole exception is when you need to manage objects that hold resources<br />
acquired by native methods. For these reasons and others, work hard to avoid writing or using classes with finalizers<br />
(other than the platform library classes) [EJ Item 6].<br />
<br />
Chapter 8: Applying Thread Pools<br />
================================<br />
>Tasks that use ThreadLocal. ThreadLocal allows each thread to have its own private "version" of a variable. However,<br />
executors are free to reuse threads as they see fit. The standard Executor implementations may reap idle threads when<br />
demand is low and add new ones when demand is high, and also replace a worker thread with a fresh one if an<br />
unchecked exception is thrown from a task. ThreadLocal makes sense to use in pool threads only if the thread local<br />
value has a lifetime that is bounded by that of a task; Thread-Local should not be used in pool threads to communicate<br />
values between tasks.<br />
<br />
8.1.1. Thread Starvation Deadlock<br />
----------------------------------------<br />
If tasks that depend on other tasks execute in a thread pool, they can deadlock. In a single threaded executor, a task<br />
that submits another task to the same executor and waits for its result will always deadlock. The second task sits on the<br />
work queue until the first task completes, but the first will not complete because it is waiting for the result of the<br />
second task. The same thing can happen in larger thread pools if all threads are executing tasks that are blocked waiting<br />
for other tasks still on the work queue. This is called thread starvation deadlock, and can occur whenever a pool task<br />
initiates an unbounded blocking wait for some resource or condition that can succeed only through the action of<br />
<br />
another pool task, such as waiting for the return value or side effect of another task, unless you can guarantee that the<br />
pool is large enough.<br />
<br />
Sizing Thread Pools<br />
-------------------<br />
To size a thread pool properly, you need to understand your computing environment, your resource budget, and the<br />
nature of your tasks. How many processors does the deployment system have ?How much memory ?Do tasks perform<br />
mostly computation, I/O, or some combination ?Do they require a scarce resource, such as a JDBC connection ?If you<br />
have different categories of tasks with very different behaviors, consider using multiple thread pools so each can be<br />
tuned according to its workload.<br />
For compute intensive tasks, an Ncpu processor system usually achieves optimum utilization with a thread pool of Ncpu<br />
+1 threads. (Even compute intensive threads occasionally take a page fault or pause for some other reason, so an<br />
"extra" runnable thread prevents CPU cycles from going unused when this happens.) For tasks that also include I/O or<br />
other blocking operations, you want a larger pool, since not all of the threads will be schedulable at all times. In order to<br />
size the pool properly, you must estimate the ratio of waiting time to compute time for your tasks; this estimate need<br />
not be precise and can be obtained through pro filing or instrumentation. Alternatively, the size of the thread pool can<br />
be tuned by running the application using several different pool sizes under a benchmark load and observing the level of<br />
CPU utilization.<br />
Given these definitions:<br />
= number of CPUs<br />
= target CPU utilization, <br />
<br />
= ratio of wait time to compute time<br />
The optimal pool size for keeping the processors at the desired utilization is:<br />
<br />
<br />
<br />
<br />
You can determine the number of CPUs using Runtime:<br />
int N_CPUS = Runtime.getRuntime().availableProcessors();<br />
<br />
>Of course, CPU cycles are not the only resource you might want to manage using thread pools. Other resources that can<br />
contribute to sizing constraints are memory, file handles, socket handles, and database connections. Calculating pool<br />
size constraints for these types of resources is easier: just add up how much of that resource each task requires and<br />
divide that into the total quantity available. The result will be an upper bound on the pool size.<br />
When tasks require a pooled resource such as database connections, thread pool size and resource pool size affect each<br />
other. If each task requires a connection, the effective size of the thread pool is limited by the connection pool size.<br />
Similarly, when the only consumers of connections are pool tasks, the effective size of the connection pool is limited by<br />
the thread pool size.<br />
<br />
>we can create different types of thread pools using Executors; but to vary the nature of thread pools(size, queueing, creation of threads, etc) you can use ThreadPoolExecutor; say configuration of a thread pool<br />
<br />
core size - size of the thread pool in normal situation<br />
max pool size - pool size can go up to this point if thread pool is busy; but always attempt to stay at core size whenever idle threads present<br />
keep alive time - maximum time a thread can be idle; after this if the pool size is greater than core size, this thread will be terminated<br />
<br />
>when ThreadPoolExecutor is created not all threads are created; as and when tasks are submitted, threads are created; unless you call prestartAllCoreThreads<br />
<br />
> Developers are sometimes tempted to set the core size to zero so that the worker threads will eventually be torn down and therefore won't<br />
prevent the JVM from exiting, but this can cause some strange seeming behavior in thread pools that don't use a SynchronousQueue for their<br />
work queue (as newCachedThreadPool does). If the pool is already at the core size, ThreadPoolExecutor creates a new thread only if<br />
the work queue is full. So tasks submitted to a thread pool with a work queue that has any capacity and a core size of zero will not execute until<br />
the queue fills up, which is usually not what is desired. In Java 6, allowCoreThreadTimeOut allows you to request that all pool threads be<br />
able to time out; enable this feature with a core size of zero if you want a bounded thread pool with a bounded work queue but still have all the<br />
threads torn down when there is no work to do.<br />
Listing 8.2. General Constructor for ThreadPoolExecutor.<br />
public ThreadPoolExecutor(int corePoolSize,<br />
int maximumPoolSize,<br />
long keepAliveTime,<br />
TimeUnit unit,<br />
BlockingQueue<runnable> workQueue,</runnable><br />
ThreadFactory threadFactory,<br />
RejectedExecutionHandler handler) { ... }<br />
<br />
>The newFixedThreadPool factory sets both the core pool size and the maximum pool size to the requested pool size,<br />
creating the effect of infinite timeout; the newCachedThreadPool factory sets the maximum pool size to<br />
Integer.MAX_VALUE and the core pool size to zero with a timeout of one minute, creating the effect of an infinitely<br />
expandable thread pool that will contract again when demand decreases. Other combinations are possible using the<br />
explicit ThreadPool-Executor constructor.<br />
<br />
>For very large or unbounded pools, you can also bypass queuing entirely and instead hand off tasks directly from<br />
producers to worker threads using a SynchronousQueue. A SynchronousQueue is not really a queue at all, but a<br />
mechanism for managing handoffs between threads. In order to put an element on a SynchronousQueue, another<br />
thread must already be waiting to accept the handoff. If no thread is waiting but the current pool size is less than the<br />
maximum, Thread-PoolExecutor creates a new thread; otherwise the task is rejected according to the saturation<br />
policy. Using a direct handoff is more efficient because the task can be handed right to the thread that will execute it,<br />
rather than first placing it on a queue and then having the worker thread fetch it from the queue. SynchronousQueue is<br />
a practical choice only if the pool is unbounded or if rejecting excess tasks is acceptable. The newCachedThreadPool<br />
factory uses a SynchronousQueue.<br />
<br />
>The newCachedThreadPool factory is a good default choice for an Executor, providing better queuing performance<br />
than a fixed thread pool.[5] A fixed size thread pool is a good choice when you need to limit the number of concurrent<br />
tasks for resource management purposes, as in a server application that accepts requests from network clients and<br />
would otherwise be vulnerable to overload.<br />
<br />
[5] This performance difference comes from the use of SynchronousQueue instead of LinkedBlocking-Queue. SynchronousQueue<br />
was replaced in Java 6 with a new non blocking algorithm that improved throughput in Executor benchmarks by a factor of three over the Java<br />
5.0 SynchronousQueue implementation (Scherer et al., 2006).<br />
Bounding either the thread pool or the work queue is suitable only when tasks are independent. With tasks that depend<br />
on other tasks, bounded thread pools or queues can cause thread starvation deadlock; instead, use an unbounded pool<br />
configuration like newCachedThreadPool.[6]<br />
[6] An alternative configuration for tasks that submit other tasks and wait for their results is to use a bounded thread pool, a<br />
SynchronousQueue as the work queue, and the caller runs saturation policy.<br />
<br />
8.3.3. Saturation Policies<br />
--------------------------<br />
When a bounded work queue fills up, the saturation policy comes into play. The saturation policy for a<br />
ThreadPoolExecutor can be modified by calling setRejectedExecutionHandler. (The saturation policy is also used<br />
when a task is submitted to an Executor that has been shut down.) Several implementations of<br />
RejectedExecutionHandler are provided, each implementing a different saturation policy: AbortPolicy,<br />
CallerRunsPolicy, DiscardPolicy, and DiscardOldestPolicy.<br />
The default policy, abort, causes execute to throw the unchecked Rejected-ExecutionException; the caller can catch<br />
this exception and implement its own overflow handling as it sees fit. The discard policy silently discards the newly<br />
submitted task if it cannot be queued for execution; the discard oldest policy discards the task that would otherwise be<br />
executed next and tries to resubmit the new task. (If the work queue is a priority queue, this discards the highest<br />
priority element, so the combination of a discard oldest saturation policy and a priority queue is not a good one.)<br />
<br />
>The caller runs policy implements a form of throttling that neither discards tasks nor throws an exception, but instead<br />
tries to slow down the flow of new tasks by pushing some of the work back to the caller. It executes the newly<br />
submitted task not in a pool thread, but in the thread that calls execute. If we modified our WebServer example to use<br />
a bounded queue and the caller runs policy, after all the pool threads were occupied and the work queue filled up the<br />
next task would be executed in the main thread during the call to execute. Since this would probably take some time,<br />
the main thread cannot submit any more tasks for at least a little while, giving the worker threads some time to catch<br />
up on the backlog. The main thread would also not be calling accept during this time, so incoming requests will queue<br />
up in the TCP layer instead of in the application. If the overload persisted, eventually the TCP layer would decide it has<br />
queued enough connection requests and begin discarding connection requests as well. As the server becomes<br />
overloaded, the overload is gradually pushed outward from the pool threads to the work queue to the application to<br />
the TCP layer, and eventually to the client enabling more graceful degradation under load.<br />
<br />
Listing 8.3. Creating a Fixed sized Thread Pool with a Bounded Queue and the Caller runs Saturation Policy.<br />
ThreadPoolExecutor executor<br />
= new ThreadPoolExecutor(N_THREADS, N_THREADS,<br />
0L, TimeUnit.MILLISECONDS,<br />
new LinkedBlockingQueue<runnable>(CAPACITY));</runnable><br />
executor.setRejectedExecutionHandler(<br />
new ThreadPoolExecutor.CallerRunsPolicy());<br />
<br />
8.3.4. Thread Factories<br />
----------------------------<br />
Whenever a thread pool needs to create a thread, it does so through a thread factory (see Listing 8.5). The default<br />
thread factory creates a new, nondaemon thread with no special configuration. Specifying a thread factory allows you to<br />
customize the configuration of pool threads. ThreadFactory has a single method, newThread, that is called whenever a<br />
thread pool needs to create a new thread.<br />
There are a number of reasons to use a custom thread factory. You might want to specify an<br />
UncaughtExceptionHandler for pool threads, or instantiate an instance of a custom Thread class, such as one that<br />
performs debug logging. You might want to modify the priority (generally not a very good idea; see Section 10.3.1) or<br />
set the daemon status (again, not all that good an idea; see Section 7.4.2) of pool threads. Or maybe you just want to<br />
give pool threads more meaningful names to simplify interpreting thread dumps and error logs.<br />
<br />
Listing 8.5. ThreadFactory Interface.<br />
public interface ThreadFactory {<br />
Thread newThread(Runnable r);<br />
}<br />
<br />
>The interesting customization takes place in MyAppThread, shown in Listing 8.7, which lets you provide a thread name,<br />
sets a custom UncaughtException-Handler that writes a message to a Logger, maintains statistics on how many<br />
threads have been created and destroyed, and optionally writes a debug message to the log when a thread is created or<br />
terminates.<br />
If your application takes advantage of security policies to grant permissions to particular codebases, you may want to<br />
use the privilegedThreadFactory factory method in Executors to construct your thread factory. It creates pool<br />
threads that have the same permissions, AccessControlContext, and contextClassLoader as the thread creating the<br />
privilegedThreadFactory. Otherwise, threads created by the thread pool inherit permissions from whatever client<br />
happens to be calling execute or submit at the time a new thread is needed, which could cause confusing security<br />
related exceptions.<br />
<br />
8.3.5. Customizing ThreadPoolExecutor After Construction<br />
--------------------------------------------------------<br />
Most of the options passed to the ThreadPoolExecutor constructors can also be modified after construction via setters<br />
(such as the core thread pool size, maximum thread pool size, keep alive time, thread factory, and rejected execution<br />
handler). If the Executor is created through one of the factory methods in Executors (except<br />
newSingleThreadExecutor), you can cast the result to Thread-PoolExecutor to access the setters as in Listing 8.8.<br />
Executors includes a factory method, unconfigurableExecutorService, which takes an existing ExecutorService<br />
and wraps it with one exposing only the methods of ExecutorService so it cannot be further configured. Unlike the<br />
pooled implementations, newSingleThreadExecutor returns an ExecutorService wrapped in this manner, rather than<br />
a raw ThreadPoolExecutor. While a single threaded executor is actually implemented as a thread pool with one<br />
thread, it also promises not to execute tasks concurrently. If some misguided code were to increase the pool size on a<br />
single threaded executor, it would undermine the intended execution semantics.<br />
<br />
8.4. Extending ThreadPoolExecutor<br />
---------------------------------<br />
ThreadPoolExecutor was designed for extension, providing several "hooks" for subclasses to override beforeExecute,<br />
afterExecute, and terminate that can be used to extend the behavior of ThreadPoolExecutor.<br />
The beforeExecute and afterExecute hooks are called in the thread that executes the task, and can be used for<br />
adding logging, timing, monitoring, or statistics gathering. The afterExecute hook is called whether the task completes<br />
by returning normally from run or by throwing an Exception. (If the task completes with an Error, afterExecute is not<br />
called.) If beforeExecute throws a RuntimeException, the task is not executed and afterExecute is not called.<br />
The terminated hook is called when the thread pool completes the shutdown process, after all tasks have finished and<br />
all worker threads have shut down. It can be used to release resources allocated by the Executor during its lifecycle,<br />
perform notification or logging, or finalize statistics gathering.<br />
<br />
<br />
>Sequential loop iterations are suitable for parallelization when each iteration is independent of the others and the work<br />
done in each iteration of the loop body is significant enough to offset the cost of managing a new task.<br />
<br />
Chapter 13: Explicit Locks<br />
==========================<br />
<br />
>Lock and ReentrantLock<br />
<br />
Why create a new locking mechanism that is so similar to intrinsic locking ?Intrinsic locking works fine in most situations<br />
but has some functional limitations it is not possible to interrupt a thread waiting to acquire a lock, or to attempt to<br />
acquire a lock without being willing to wait for it forever. Intrinsic locks also must be released in the same block of code<br />
in which they are acquired; this simplifies coding and interacts nicely with exception handling, but makes non block<br />
structured locking disciplines impossible. None of these are reasons to abandon synchronized, but in some cases a<br />
more flexible locking mechanism offers better liveness or performance.<br />
<br />
>With intrinsic locks, a deadlock is fatal the only way to recover is to restart the application,<br />
and the only defense is to construct your program so that inconsistent lock ordering is impossible. Timed and polled locking offer another option: probabilistic deadlock avoidance.<br />
<br />
>lockInterruptibly() is useful for implementing cancellable tasks<br />
<br />
> When we started this book, ReentrantLock seemed the last word in lock scalability. Less than a year later, intrinsic locking gives it a good run for its money. Performance is not just a moving target, it can be a fast moving target.<br />
<br />
>the comparative advantage of explicit locks over intrinsic went down in Java 6 from what it was in Java 5 because intrinsic locks improved in Java6<br />
<br />
>With a fair lock, a newly requesting thread is queued if the lock is held by another thread or if threads are queued waiting for the lock; with a nonfair lock, the thread is queued only if the lock is currently held.[4]<br />
[4] The polled tryLock always barges, even for fair locks.<br />
<br />
#otherwise there is no point in having tryLock() method if it can't barge in?!<br />
<br />
>usually non-fair locks have higher throughput than fair lock because of reduced time spent in queueing threads<br />
>concurrent collections have even higher throughput than non-fair locks<br />
<br />
>auto lock release of intrinsic locking is a far greater advantage over the explicit locks; use explicit locks only when you can't achieve what you want with synchronized code<br />
<br />
A warning cry<br />
-------------<br />
Under Java 5.0, intrinsic locking has another advantage over ReentrantLock: thread dumps show which call frames<br />
acquired which locks and can detect and identify deadlocked threads. The JVM knows nothing about which threads hold<br />
ReentrantLocks and therefore cannot help in debugging threading problems using ReentrantLock. This disparity is<br />
addressed in Java 6 by providing a management and monitoring interface with which locks can register, enabling locking<br />
information for ReentrantLocks to appear in thread dumps and through other management and debugging interfaces.<br />
The availability of this information for debugging is a substantial, if mostly temporary, advantage for synchronized;<br />
locking information in thread dumps has saved many programmers from utter consternation. The non block structured<br />
nature of ReentrantLock still means that lock acquisitions cannot be tied to specific stack frames, as they can with<br />
intrinsic locks.<br />
Future performance improvements are likely to favor synchronized over ReentrantLock. Because synchronized is<br />
built into the JVM, it can perform optimizations such as lock elision for thread confined lock objects and lock coarsening<br />
to eliminate synchronization with intrinsic locks (see Section 11.3.2); doing this with library based locks seems far less<br />
likely. Unless you are deploying on Java 5.0 for the foreseeable future and you have a demonstrated need for<br />
ReentrantLock's scalability benefits on that platform, it is not a good idea to choose ReentrantLock over<br />
synchronized for performance reasons.<br />
<br />
ReadWrite Lock<br />
--------------<br />
>read write locks allow: a resource can be accessed by multiple readers or a single<br />
writer at a time, but not both.<br />
<br />
>The interaction between the read and write locks allows for a number of possible implementations. Some of the<br />
implementation options for a ReadWriteLock are:<br />
Release preference. When a writer releases the write lock and both readers and writers are queued up, who should be<br />
given preference readers, writers, or whoever asked first ?<br />
Reader barging. If the lock is held by readers but there are waiting writers, should newly arriving readers be granted<br />
immediate access, or should they wait behind the writers ? Allowing readers to barge ahead of writers enhances<br />
concurrency but runs the risk of starving writers.<br />
Reentrancy. Are the read and write locks reentrant ?<br />
Downgrading. If a thread holds the write lock, can it acquire the read lock without releasing the write lock ?This would<br />
let a writer "downgrade" to a read lock without letting other writers modify the guarded resource in the meantime.<br />
Upgrading. Can a read lock be upgraded to a write lock in preference to other waiting readers or writers ?Most read<br />
write lock implementations do not support upgrading, because without an explicit upgrade operation it is deadlock<br />
prone. (If two readers simultaneously attempt to upgrade to a write lock, neither will release the read lock.)<br />
ReentrantReadWriteLock provides reentrant locking semantics for both locks. Like ReentrantLock, a<br />
ReentrantReadWriteLock can be constructed as non fair (the default) or fair. With a fair lock, preference is given to the<br />
thread that has been waiting the longest; if the lock is held by readers and a thread requests the write lock, no more<br />
readers are allowed to acquire the read lock until the writer has been serviced and releases the write lock. With a non<br />
fair lock, the order in which threads are granted access is unspecified. Downgrading from writer to reader is permitted;<br />
upgrading from reader to writer is not (attempting to do so results in deadlock).<br />
Like ReentrantLock, the write lock in ReentrantReadWriteLock has a unique owner and can be released only by the<br />
thread that acquired it. In Java 5.0, the read lock behaves more like a Semaphore than a lock, maintaining only the count<br />
of active readers, not their identities. This behavior was changed in Java 6 to keep track also of which threads have been<br />
granted the read lock. [6]<br />
[6] One reason for this change is that under Java 5.0, the lock implementation cannot distinguish between a thread requesting the read lock for the<br />
first time and a reentrant lock request, which would make fair read write locks deadlock prone.<br />
Read write locks can improve concurrency when locks are typically held for a moderately long time and most operations<br />
do not modify the guarded resources. ReadWriteMap in Listing 13.7 uses a ReentrantReadWriteLock to wrap a Map so<br />
that it can be shared safely by multiple readers and still prevent reader writer or writer writer conflicts.[7] In reality,<br />
ConcurrentHashMap's performance is so good that you would probably use it rather than this approach if all you<br />
needed was a concurrent hash based map, but this technique would be useful if you want to provide more concurrent<br />
access to an alternate Map implementation such as LinkedHashMap.<br />
[7] ReadWriteMap does not implement Map because implementing the view methods such as entrySet and values would be difficult and<br />
the "easy" methods are usually sufficient.<br />
<br />
Chapter 14:Building Custom Synchronizers<br />
========================================<br />
>Every call to wait is implicitly associated with a specific condition predicate. When calling wait regarding a particular condition predicate, the caller must already hold the lock associated with the condition queue, and that lock must also guard the state variables from which the condition predicate is composed.<br />
<br />
>When control re enters the code calling wait, it has reacquired the lock associated with the condition queue. Is the condition predicate now true ?Maybe. It might have been true at the time the notifying thread called notifyAll, but could have become false again by the time you reacquire the lock. Other threads may have acquired the lock and changed the object's state between when your thread was awakened and when wait reacquired the lock. Or maybe it hasn't been true at all since you called wait. You don't know why another thread called notify or notifyAll; maybe it was because another condition predicate associated with the same condition queue became true. Multiple condition predicates per condition queue are quite common BoundedBuffer uses the same condition queue for both the "not full" and "not empty" predicates.[9]<br />
<br />
>For all these reasons, when you wake up from wait you must test the condition predicate again, and go back to waiting<br />
(or fail) if it is not yet true. Since you can wake up repeatedly without your condition predicate being true, you must<br />
therefore always call wait from within a loop, testing the condition predicate in each iteration. The canonical form for a<br />
condition wait is shown in Listing 14.7.<br />
Listing 14.7. Canonical Form for State dependent Methods.<br />
void stateDependentMethod() throws InterruptedException {<br />
// condition predicate must be guarded by lock<br />
synchronized(lock) {<br />
while (!conditionPredicate())<br />
lock.wait();<br />
// object is now in desired state<br />
}<br />
}<br />
<br />
>When using condition waits (Object.wait or Condition.await):<br />
Always have a condition predicate some test of object state that must hold before proceeding;<br />
Always test the condition predicate before calling wait, and again after returning from wait;<br />
Always call wait in a loop;<br />
Ensure that the state variables making up the condition predicate are guarded by the lock associated with the condition queue;<br />
Hold the lock associated with the condition queue when calling wait, notify, or notifyAll; and<br />
Do not release the lock after checking the condition predicate but before acting on it.<br />
<br />
>Missing signals: if you miss the signal that comes before waiting, you end up waiting forever. so check the condition before calling wait(while holding the lock) as shown in the previous code sample<br />
<br />
>Whenever you wait on a condition, make sure that someone will perform a notification whenever the condition predicate becomes true.<br />
<br />
>when two threads wait on different conditions on the same object, a single notify() might wake up the wrong thread and target thread may wait forever for the hijacked notify; so use notifyAll()<br />
<br />
>Single notify can be used instead of notifyAll only when both of the following conditions hold:<br />
Uniform waiters. Only one condition predicate is associated with the condition queue, and each thread executes the<br />
same logic upon returning from wait; and One in, one out. A notification on the condition variable enables at most one thread to proceed.<br />
<br />
#latch that lets multiple threads in is not a candidate for single notify<br />
#bounded buffer where threads might wait for two different conditions(empty or full) again is not a candidate for single notify<br />
<br />
>but single notify() is efficient than notifyAll() if we could use it<br />
<br />
> If ten threads are waiting on a condition<br />
queue, calling notifyAll causes each of them to wake up and contend for the lock; then most or all of them will go<br />
right back to sleep. This means a lot of context switches and a lot of contended lock acquisitions for each event that<br />
enables (maybe) a single thread to make progress. (In the worst case, using notify-All results in O(n^2) wakeups where<br />
n would suffice.) This is another situation where performance concerns support one approach and safety concerns<br />
support the other.<br />
<br />
>a notification is performed every time an<br />
object is put into or removed from the buffer. This could be optimized by observing that a thread can be released from a<br />
wait only if the buffer goes from empty to not empty or from full to not full, and notifying only if a put or take effected<br />
one of these state transitions. This is called conditional notification. While conditional notification can improve<br />
performance, it is tricky to get right (and also complicates the implementation of subclasses) and so should be used<br />
carefully.<br />
Single notification and conditional notification are optimizations. As always, follow the principle "First make it right, and<br />
then make it fastif it is not already fast enough" when using these optimizations; it is easy to introduce strange liveness<br />
failures by applying them incorrectly.<br />
<br />
>AbstractQueuedSynchronizer, upon which most of the state dependent classes in java.util.concurrent are built<br />
(see Section 14.4), exploits the concept of exit protocol. Rather than letting synchronizer classes perform their own<br />
notification, it instead requires synchronizer methods to return a value indicating whether its action might have<br />
unblocked one or more waiting threads. This explicit API requirement makes it harder to "forget" to notify on some<br />
state transitions.<br />
<br />
>Intrinsic condition queues have several drawbacks. Each intrinsic lock can have only one associated condition queue,<br />
which means that in classes like BoundedBuffer multiple threads might wait on the same condition queue for different<br />
condition predicates, and the most common pattern for locking involves exposing the condition queue object. Both of<br />
these factors make it impossible to enforce the uniform waiter requirement for using notifyAll. If you want to write a<br />
concurrent object with multiple condition predicates, or you want to exercise more control over the visibility of the<br />
condition queue, the explicit Lock and Condition classes offer a more flexible alternative to intrinsic locks and<br />
condition queues.<br />
<br />
>A Condition is associated with a single Lock, just as a condition queue is associated with a single intrinsic lock; to create<br />
a Condition, call Lock.newCondition on the associated lock. And just as Lock offers a richer feature set than intrinsic<br />
locking, Condition offers a richer feature set than intrinsic condition queues: multiple wait sets per lock, interruptible<br />
and uninterruptible condition waits, deadline based waiting, and a choice of fair or nonfair queueing.<br />
Listing 14.10. Condition Interface.<br />
public interface Condition {<br />
void await() throws InterruptedException;<br />
boolean await(long time, TimeUnit unit)<br />
throws InterruptedException;<br />
long awaitNanos(long nanosTimeout) throws InterruptedException;<br />
void awaitUninterruptibly();<br />
boolean awaitUntil(Date deadline) throws InterruptedException;<br />
void signal();<br />
void signalAll();<br />
}<br />
<br />
>Unlike intrinsic condition queues, you can have as many Condition objects per Lock as you want. Condition objects<br />
inherit the fairness setting of their associated Lock; for fair locks, threads are released from Condition.await in FIFO<br />
order.<br />
Hazard warning: The equivalents of wait, notify, and notifyAll for Condition objects are await, signal, and<br />
signalAll. However, Condition extends Object, which means that it also has wait and notify methods. Be sure to<br />
use the proper versions await and signal - instead!<br />
<br />
> ReentrantLock requires that the Lock be held when calling signal or signalAll, but Lock implementations are permitted to<br />
construct Conditions that do not have this requirement.<br />
<br />
14.4. Anatomy of a Synchronizer<br />
-------------------------------<br />
>The interfaces of ReentrantLock and Semaphore have a lot in common. Both classes act as a "gate", allowing only a limited number of threads to pass at a time; threads arrive at the gate and are allowed through (lock or acquire returns successfully), are made to wait (lock or acquire blocks), or are turned away (tryLock or tryAcquire returns false, indicating that the lock or permit did not become available in the time allowed). Further, both allow interruptible, uninterruptible, and timed acquisition attempts, and both allow a choice of fair or nonfair queueing of waiting threads.<br />
<br />
>it is a common exercise to prove that a counting semaphore can be implemented using a lock (as in SemaphoreOnLock in Listing 14.12) and that a lock can be implemented using a counting semaphore.<br />
In actuality, they are both implemented using a common base class, Abstract-QueuedSynchronizer (AQS)as are many<br />
other synchronizers. AQS is a framework for building locks and synchronizers, and a surprisingly broad range of synchronizers can be built easily and efficiently using it. Not only are ReentrantLock and Semaphore built using AQS, but so are CountDownLatch, ReentrantReadWriteLock, SynchronousQueue,[12] and FutureTask.<br />
[12] Java6 replaces the AQS based SynchronousQueue with a (more scalable) non blocking version.<br />
<br />
>Using AQS to build synchronizers offers several benefits. Not only does it substantially reduce the implementation effort, but you also needn't pay for multiple points of contention, as you would when constructing one synchronizer on top of another. In SemaphoreOnLock, acquiring a permit has two places where it might block once at the lock guarding the semaphore state, and then again if a permit is not available. Synchronizers built with AQS have only one point where they might block, reducing context switch overhead and improving throughput. AQS was designed for scalability, and all the synchronizers in java.util.concurrent that are built with AQS benefit from this.<br />
<br />
AbstractQueuedSynchronizer<br />
--------------------------<br />
>For a class to be state dependent, it must have some state. AQS takes on the task of managing some of the state for the synchronizer class: it manages a single integer of state information that can be manipulated through the protected getState, setState, and compareAndSetState methods. This can be used to represent arbitrary state; for example, ReentrantLock uses it to represent the count of times the owning thread has acquired the lock, Semaphore uses it to represent the number of permits remaining, and FutureTask uses it to represent the state of the task (not yet started, running, completed, cancelled). Synchronizers can also manage additional state variables themselves; for example, ReentrantLock keeps track of the current lock owner so it can distinguish between reentrant and contended lock acquisition requests.<br />
<br />
>Acquisition and release in AQS take the forms shown in Listing 14.13. Depending on the synchronizer, acquisition might be exclusive, as with Reentrant-Lock, or nonexclusive, as with Semaphore and CountDownLatch. An acquire operation has two parts. First, the synchronizer decides whether the current state permits acquisition; if so, the thread is allowed to proceed, and if not, the acquire blocks or fails. This decision is determined by the synchronizer semantics; for example, acquiring a lock can succeed if the lock is unheld, and acquiring a latch can succeed if the latch is in its terminal state.<br />
The second part involves possibly updating the synchronizer state; one thread acquiring the synchronizer can affect whether other threads can acquire it. For example, acquiring a lock changes the lock state from "unheld" to "held", and acquiring a permit from a Semaphore reduces the number of permits left. On the other hand, the acquisition of a latch by one thread does not affect whether other threads can acquire it, so acquiring a latch does not change its state.<br />
<br />
Listing 14.13. Canonical Forms for Acquisition and Release in AQS.<br />
boolean acquire() throws InterruptedException {<br />
<br />
while (state does not permit acquire) {<br />
if (blocking acquisition requested) {<br />
enqueue current thread if not already queued<br />
block current thread<br />
}<br />
else<br />
return failure<br />
}<br />
<br />
possibly update synchronization state<br />
dequeue thread if it was queued<br />
return success<br />
}<br />
void release() {<br />
update synchronization state<br />
if (new state may permit a blocked thread to acquire)<br />
unblock one or more queued threads<br />
}<br />
<br />
>A synchronizer supporting exclusive acquisition should implement the protected methods TRyAcquire, TRyRelease,<br />
and isHeldExclusively, and those supporting shared acquisition should implement tryAcquireShared and<br />
TRyReleaseShared. The acquire, acquireShared, release, and releaseShared methods in AQS call the TRy forms of<br />
these methods in the synchronizer subclass to determine if the operation can proceed. The synchronizer subclass can<br />
use getState, setState, and compareAndSetState to examine and update the state according to its acquire and<br />
release semantics, and informs the base class through the return status whether the attempt to acquire or release the<br />
synchronizer was successful. For example, returning a negative value from TRyAcquireShared indicates acquisition<br />
failure; returning zero indicates the synchronizer was acquired exclusively; and returning a positive value indicates the<br />
synchronizer was acquired nonexclusively. The TRyRelease and TRyReleaseShared methods should return true if the<br />
release may have unblocked threads attempting to acquire the synchronizer.<br />
To simplify implementation of locks that support condition queues (like ReentrantLock), AQS also provides machinery<br />
for constructing condition variables associated with synchronizers.<br />
<br />
14.5.1. A Simple Latch<br />
---------------------------<br />
OneShotLatch in Listing 14.14 is a binary latch implemented using AQS. It has two public methods, await and signal,<br />
that correspond to acquisition and release. Initially, the latch is closed; any thread calling await blocks until the latch is<br />
opened. Once the latch is opened by a call to signal, waiting threads are released and threads that subsequently arrive<br />
at the latch will be allowed to proceed.<br />
<br />
Listing 14.14. Binary Latch Using AbstractQueuedSynchronizer.<br />
@ThreadSafe<br />
public class OneShotLatch {<br />
private final Sync sync = new Sync();<br />
public void signal() { sync.releaseShared(0); }<br />
public void await() throws InterruptedException {<br />
sync.acquireSharedInterruptibly(0);<br />
}<br />
private class Sync extends AbstractQueuedSynchronizer {<br />
protected int tryAcquireShared(int ignored) {<br />
// Succeed if latch is open (state == 1), else fail<br />
return (getState() == 1) ? 1 : -1;<br />
}<br />
protected boolean tryReleaseShared(int ignored) {<br />
setState(1); // Latch is now open<br />
return true; // Other threads may now be able to acquire<br />
}<br />
}<br />
}<br />
In OneShotLatch, the AQS state holds the latch state closed (zero) or open (one). The await method calls<br />
acquireSharedInterruptibly in AQS, which in turn consults the TRyAcquireShared method in OneShotLatch. The<br />
tryAcquire-Shared implementation must return a value indicating whether or not acquisition can proceed. If the latch<br />
has been previously opened, tryAcquireShared returns success, allowing the thread to pass; otherwise it returns a<br />
value indicating that the acquisition attempt failed. The acquireSharedInterruptibly method interprets failure to<br />
mean that the thread should be placed on the queue of waiting threads. Similarly, signal calls releaseShared, which<br />
causes tryReleaseShared to be consulted. The TRyReleaseShared implementation unconditionally sets the latch state<br />
to open and indicates (through its return value) that the synchronizer is in a fully released state. This causes AQS to let<br />
all waiting threads attempt to reacquire the synchronizer, and acquisition will now succeed because tryAcquireShared<br />
returns success.<br />
OneShotLatch is a fully functional, usable, performant synchronizer, implemented in only twenty or so lines of code. Of<br />
course, it is missing some useful feature such as timed acquisition or the ability to inspect the latch statebut these are<br />
easy to implement as well, since AQS provides timed versions of the acquisition methods and utility methods for<br />
common inspection operations.<br />
OneShotLatch could have been implemented by extending AQS rather than delegating to it, but this is undesirable for<br />
several reasons [EJ Item 14]. Doing so would undermine the simple (two method) interface of OneShotLatch, and while<br />
the public methods of AQS won't allow callers to corrupt the latch state, callers could easily use them incorrectly. None<br />
of the synchronizers in java.util.concurrent extends AQS directly they all delegate to private inner subclasses of<br />
AQS instead.<br />
<br />
14.6.1. ReentrantLock<br />
----------------------<br />
ReentrantLock supports only exclusive acquisition, so it implements tryAcquire, tryRelease, and<br />
isHeldExclusively; tryAcquire for the non fair version is shown in Listing 14.15. ReentrantLock uses the<br />
synchronization state to hold the lock acquisition count, and maintains an owner variable holding the identity of the<br />
owning thread that is modified only when the current thread has just acquired the lock or is just about to release it.[14] In<br />
tryRelease, it checks the owner field to ensure that the current thread owns the lock before allowing an unlock to<br />
proceed; in tryAcquire, it uses this field to differentiate between a reentrant acquisition and a contended acquisition<br />
attempt.<br />
[14] Because the protected state manipulation methods have the memory semantics of a volatile read or write and ReentrantLock is careful to<br />
read the owner field only after calling getState and write it only before calling setState, ReentrantLock can piggyback on the memory<br />
semantics of the synchronization state, and thus avoid further synchronization see Section 16.1.4.<br />
When a thread attempts to acquire a lock, tryAcquire first consults the lock state. If it is unheld, it tries to update the<br />
lock state to indicate that it is held. Because the state could have changed since it was first inspected a few instructions<br />
ago, tryAcquire uses compareAndSetState to attempt to atomically update the state to indicate that the lock is now<br />
held and confirm that the state has not changed since last observed. (See the description of compareAndSet in Section<br />
15.3.) If the lock state indicates that it is already held, if the current thread is the owner of the lock, the acquisition<br />
count is incremented; if the current thread is not the owner of the lock, the acquisition attempt fails.<br />
Listing 14.15. tryAcquire Implementation From Non fair ReentrantLock.<br />
protected boolean tryAcquire(int ignored) {<br />
final Thread current = Thread.currentThread();<br />
int c = getState();<br />
if (c == 0) {<br />
if (compareAndSetState(0, 1)) {<br />
owner = current;<br />
return true;<br />
}<br />
} else if (current == owner) {<br />
setState(c+1);<br />
return true;<br />
}<br />
return false;<br />
}<br />
ReentrantLock also takes advantage of AQS's built in support for multiple condition variables and wait sets.<br />
Lock.newCondition returns a new instance of ConditionObject, an inner class of AQS.<br />
<br />
>semaphore types of synchronizers only override xxxsharedxxx() versions of methods in AQS<br />
<br />
14.6.2. Semaphore and CountDownLatch<br />
---------------------------------------<br />
Semaphore uses the AQS synchronization state to hold the count of permits currently available. The tryAcquireShared<br />
method (see Listing 14.16) first computes the number of permits remaining, and if there are not enough, returns a value<br />
indicating that the acquire failed. If sufficient permits appear to be left, it attempts to atomically reduce the permit<br />
count using compareAndSetState. If that succeeds (meaning that the permit count had not changed since it last<br />
looked), it returns a value indicating that the acquire succeeded. The return value also encodes whether other shared<br />
acquisition attempts might succeed, in which case other waiting threads will also be unblocked.<br />
The while loop terminates either when there are not enough permits or when TRyAcquireShared can atomically<br />
update the permit count to reflect acquisition. While any given call to compareAndSetState may fail due to contention<br />
with another thread (see Section 15.3), causing it to retry, one of these two termination criteria will become true within<br />
a reasonable number of retries. Similarly, tryReleaseShared increases the permit count, potentially unblocking waiting<br />
threads, and retries until the update succeeds. The return value of TRyReleaseShared indicates whether other threads<br />
might have been unblocked by the release.<br />
CountDownLatch uses AQS in a similar manner to Semaphore: the synchronization state holds the current count. The<br />
countDown method calls release, which causes the counter to be decremented and unblocks waiting threads if the<br />
counter has reached zero; await calls acquire, which returns immediately if the counter has reached zero and<br />
otherwise blocks.<br />
Listing 14.16. tryacquireshared and tryreleaseshared from Semaphore.<br />
protected int tryAcquireShared(int acquires) {<br />
while (true) {<br />
int available = getState();<br />
int remaining = available - acquires;<br />
if (remaining < 0<br />
|| compareAndSetState(available, remaining))<br />
return remaining;<br />
}<br />
}<br />
protected boolean tryReleaseShared(int releases) {<br />
while (true) {<br />
int p = getState();<br />
if (compareAndSetState(p, p + releases))<br />
return true;<br />
}<br />
}<br />
<br />
<br />
14.6.3. FutureTask<br />
-------------------<br />
At first glance, FutureTask doesn't even look like a synchronizer. But Future.get has semantics that are very similar to that of a latch if some event (the completion or cancellation of the task represented by the FutureTask) has occurred, then threads can proceed, otherwise they are queued until that event occurs.<br />
FutureTask uses the AQS synchronization state to hold the task status running, completed, or cancelled. It also maintains additional state variables to hold the result of the computation or the exception it threw. It further maintains a reference to the thread that is running the computation (if it is currently in the running state), so that it can be interrupted if the task is cancelled.<br />
<br />
14.6.4. ReentrantReadWriteLock<br />
-------------------------------<br />
The interface for ReadWriteLock suggests there are two locks; a reader lock and a writer lock;but in the AQS based implementation of ReentrantReadWriteLock, a single AQS subclass manages both read and write locking. ReentrantRead-WriteLock uses 16 bits of the state for the write lock count, and the other 16 bits for the read lock count. Operations on the read lock use the shared acquire and release methods; operations on the write lock use the exclusive acquire and release methods. Internally, AQS maintains a queue of waiting threads, keeping track of whether a thread has requested exclusive or shared access. In ReentrantRead-WriteLock, when the lock becomes available, if the thread at the head of the queue was looking for write access it will get it, and if the thread at the head of the queue was looking for read access, all<br />
queued threads up to the first writer will get it.[15]<br />
<br />
[15] This mechanism does not permit the choice of a reader preference or writer preference policy, as some read write lock implementations do. For that, either the AQS wait queue would need to be something other than a FIFO queue, or two queues would be needed. However, such a strict ordering policy is rarely needed in practice; if the nonfair version of ReentrantReadWriteLock does not offer acceptable liveness, the fair version usually provides satisfactory ordering and guarantees nonstarvation of readers and writers. <br />
<br />
<br />
====================<br />
NON-BLOCKING THREADS<br />
====================<br />
<br />
Refer <a href="http://www.ibm.com/developerworks/java/library/j-jtp04186/">http://www.ibm.com/developerworks/java/library/j-jtp04186/</a><br />
<br />
--<br />
<br />
<br />
>no locking mechanism is used to execute a critical section; all are allowed to perform their task simultaneously however, upon detection of outdated data in the middle of an atomic operation, the clients requested for atomic operation should be ready to receive aborted attempt; that is their entire operation will be cancelled and they have to try at it again<br />
<br />
>the data getting outdated in the middle of an atomic sequence is detected by 'Compare And Set' methodology where, in the final step of committing the data, once again the data is checked for consistency; setting the data is always preceded by comparing the current data with data read during the start of the atomic operation(allowing other threads to butt-in in between)<br />
<br />
>ususally CAS(Compare And Set) is provided by hardware instructions directly, and non-blocking algorithms build on these machine instructions<br />
<br />
>but however from Java 5, atomic operations related registers(data field) are provided as java atomic data types by java.util.concurrent.atomic package; these atomic data types can be used to build non-blocking algorithms in java itself now<br />
<br />
>non-blocking algorithms are fundamentally something similar to source control conflict-merge operations; for example, in CVS or ClearCase, when two different copies are committed at the same time, one succeeds and one fails; the failed copy should update its source one more time and make its changes on top of it and try to commit again and so on; this principle is used in non-blocking thread implementations<br />
<br />
>non-blocking threads should request/entrust the entire atomic operation to the data; sometimes it gets accepted, sometimes it gets rejected; upon rejection, the thread has to reupdate the data and based on the new data, it has to compile its atomic operation and try again<br />
<br />
>In locking mechanism, there is over-head of context switching, is involved when a thread has to wait for a lock; it practically gets suspended not doing any work till it acquires the lock; but in non-blocking thread situation, the thread at the worst, reattempts to modify the data couple of times instead of getting itself suspended; that is all; so throughput and performance is superior in non-blocking thread systems<br />
<br />
>but! when the contention for a resource is extremely intensive, non-blocking threads keep attempting to modify the data, and the rejection rate(attempt failed due to an update in the data) is very high; and it is very high for all threads; in this situation, blocking threads perform better because, they simply wait for the lock and taking turn nicely instead of making chaos and increasing the rejection rate<br />
<br />
>non-blocking threads can be implemented only when atomic data instruction is supported by the hardware<br />
<br />
>java atomic classes are built on top of machine level atomic instructions which are very common in todays processors; but if the underlying platform does not support machine level atomic instructions, then internal locking mechanism is used and hence it may not be an actual non-blocking thread<br />
<br />
>java atomic classes are kind of extension on volatile variables<br />
<br />
>we know that volatile variables are so volatile that care should be taken when reading and modifying them, because they can change at anytime<br />
<br />
>atomic java classes provide methods which act like they are dealing with volatile variables<br />
<br />
>some methods provide behavior 'read like you read a volatile variable' - get() method<br />
>some provide the behavior 'write like you write a volatile variable' - set()<br />
>'read and then write like you read and write(togther one after the other) a volatile variable' - compareAndSet()<br />
<br />
>as long as your atomic operation consists only one CAS operation(counter and stacks) your task ends in one do-while() loop where you keep trying till CAS succeeds; but what if your atomic operation is little complex(linked list and queues with tail) and involves two or more CAS operations; threads are thread-safe only with respect to one CAS; in this situation things can go wrong in between two CAS operations of a thread; the solution is always let every thread know clearly that some other thread is in the midst of its multiple CAS operations; this can be done by introducing code logics that look for inconsistency in the underlying data; so every thread can detect such inconsistency(in case of tailed queue, any thread can see that queue is being updated currently when it sees, its tail item has next reference; this means some thread is about to change the tail to point to actual new tail); so, instead of waiting for the thread to finish, the thread which sees the inconsistency finishes the job of the other thread and continues with its own task now; the original thread which was in the midst of updating, should check for its second CAS success status; it should perform second CAS and simply assume that it was a success; because any other thread that comes afterwards or came in between, would have done the job; otherwise, the first thread will corrupt the queue here<br />
<br />
>so a data can be in two states; one is normal state; other is quiescent state; in the second state, any thread should be able to see the inconsistency and should be able to cleanup the data on its own<br />
<br />
Usage of non-blocking algos:<br />
----------------------------<br />
>GC uses for concurrent and parallel collection<br />
>scheduler uses to schedule processes and threads<br />
>SynchronousQueue was replaced with new non-blocking version<br />
><br />
<br />
New IDEA(well, old idea only; happens in atomic update while loops and CAS):<br />
----------------------------------------------------------------------------<br />
One way to achieve non blocking concurrency is to appoint a gateway agent to the shared data and put all requests to read and modify through that agent using a queue to hold such requests; agent performs the requests one by one from the queue; (note here each request is an atomic operation(set of operations that have to be performed together or cancel everything altogether) any request that cannot be committed to the shared data(due to inconsistency arose after one of the previous requests by someone else) is rejected and a notification is sent to the requester; the requester should always wait for the success or failure nofications for his requests in order to conclude his update/read operation; upon receiving failure status, the requester has to place a fresh request.<br />
<br />
Another thing that would make everything easy is to let the said agent broadcast updates to the shared data to all threads, so that any thread is preparing itself to place a new request is well informed about the latest on going events.<br />
--x--<br />
<br />
Chapter 15: Atomic variables and non-blocking algorithms<br />
========================================================<br />
>Much of the recent research on concurrent algorithms has focused on non blocking algorithms, which use low level atomic machine instructions such as compare and swap instead of locks to ensure data integrity under concurrent access. Non blocking algorithms are used extensively in operating systems and JVMs for thread and process scheduling, garbage collection, and to implement locks and other concurrent data structures.<br />
<br />
>As of Java 5.0, it is possible to build efficient non blocking algorithms in Java using the atomic variable classes such as AtomicInteger and AtomicReference. Atomic variables can also be used as "better volatile variables" even if you are not developing non blocking algorithms. Atomic variables offer the same memory semantics as volatile variables, but with additional support for atomic updates making them ideal for counters, sequence generators, and statistics gathering while offering better scalability than lock based alternatives.<br />
<br />
>Volatile variables are a lighter weight synchronization mechanism than locking because they do not involve context switches or thread scheduling. However, volatile variables have some limitations compared to locking: while they provide similar visibility guarantees, they cannot be used to construct atomic compound actions. This means that volatile variables cannot be used when one variable depends on another, or when the new value of a variable depends on its old value. This limits when volatile variables are appropriate, since they cannot be used to reliably implement common tools such as counters or mutexes.[2]<br />
<br />
>Locking has a few other disadvantages. When a thread is waiting for a lock, it cannot do anything else. If a thread holding a lock is delayed (due to a page fault, scheduling delay, or the like), then no thread that needs that lock can make progress. This can be a serious problem if the blocked thread is a high priority thread but the thread holding the lock is a lower priority thread a performance hazard known as priority inversion. Even though the higher priority thread should have precedence, it must wait until the lock is released, and this effectively downgrades its priority to that of the lower priority thread. If a thread holding a lock is permanently blocked (due to an infinite loop, deadlock, livelock, or other liveness failure), any threads waiting for that lock can never make progress.<br />
<br />
>For lock based classes with fine grained operations (such as the synchronized collections classes, where most methods contain only a few operations), the ratio of scheduling overhead to useful work can be quite high when the lock is frequently contended.<br />
<br />
15.2. Hardware Support for Concurrency<br />
--------------------------------------<br />
Exclusive locking is a pessimistic technique it assumes the worst (if you don't lock your door, gremlins will come in and rearrange your stuff) and doesn't proceed until you can guarantee, by acquiring the appropriate locks, that other threads will not interfere. For fine grained operations, there is an alternate approach that is often more efficient the optimistic approach, whereby you proceed with an update, hopeful that you can complete it without interference. This approach relies on collision detection to determine if there has been interference from other parties during the update, in which case the operation fails and can be retried (or not). The optimistic approach is like the old saying, "It is easier to obtain forgiveness than permission", where "easier" here means "more efficient".<br />
Processors designed for multiprocessor operation provide special instructions for managing concurrent access to shared variables. Early processors had atomic test and set, fetch and increment, or swap instructions sufficient for implementing mutexes that could in turn be used to implement more sophisticated concurrent objects. Today, nearly every modern processor has some form of atomic read modify write instruction, such as compare and swap or load linked/store conditional. Operating systems and JVMs use these instructions to implement locks and concurrent data structures, but until Java 5.0 they had not been available directly to Java classes.<br />
<br />
15.2.1. Compare and Swap<br />
------------------------<br />
The approach taken by most processor architectures, including IA32 and Sparc, is to implement a compare and swap<br />
(CAS) instruction. (Other processors, such as PowerPC, implement the same functionality with a pair of instructions: loadlinked and store conditional.) CAS has three operands a memory location V on which to operate, the expected old value A, and the new value B. CAS atomically updates V to the new value B, but only if the value in V matches the expected old value A; otherwise it does nothing. In either case, it returns the value currently in V. (The variant called compare and set instead returns whether the operation succeeded.) CAS means "I think V should have the value A; if it does, put B there, otherwise don't change it but tell me I was wrong." CAS is an optimistic technique it proceeds with the update in the hope of success, and can detect failure if another thread has updated the variable since it was last examined. SimulatedCAS in Listing 15.1 illustrates the semantics (but not the implementation or performance) of CAS. When multiple threads attempt to update the same variable simultaneously using CAS, one wins and updates the variable's value, and the rest lose. But the losers are not punished by suspension, as they could be if they failed to acquire a lock; instead, they are told that they didn't win the race this time but can try again. Because a thread that<br />
loses a CAS is not blocked, it can decide whether it wants to try again, take some other recovery action, or do nothing.[3] This flexibility eliminates many of the liveness hazards associated with locking (though in unusual cases can introduce the risk of livelock see Section 10.3.3).<br />
<br />
>writing a CAS function in java or any other high level programming language is not exactly the actual CAS with actual performance benefits; you need to use CAS machine intructions(hardware support is necessary) in order to implement CAS<br />
<br />
>At first glance, the CAS based counter looks as if it should perform worse than a lock based counter; it has more operations and a more complicated control flow, and depends on the seemingly complicated CAS operation. But in reality, CAS based counters significantly outperform lock based counters if there is even a small amount of contention, and often even if there is no contention. The fast path for uncontended lock acquisition typically requires at least one CAS plus other lock related housekeeping, so more work is going on in the best case for a lock based counter than in the normal case for the CAS based counter. Since the CAS succeeds most of the time (assuming low to moderate contention), the hardware will correctly predict the branch implicit in the while loop, minimizing the overhead of the more complicated control logic.<br />
The language syntax for locking may be compact, but the work done by the JVM and OS to manage locks is not. Locking<br />
entails traversing a relatively complicated code path in the JVM and may entail OS level locking, thread suspension, and context switches. In the best case, locking requires at least one CAS, so using locks moves the CAS out of sight but doesn't save any actual execution cost. On the other hand, executing a CAS from within the program involves no JVM code, system calls, or scheduling activity. What looks like a longer code path at the application level is in fact a much shorter code path when JVM and OS activity are taken into account. The primary disadvantage of CAS is that it forces the caller to deal with contention (by retrying, backing off, or giving up), whereas locks deal with contention automatically by blocking until the lock is available.[5]<br />
[5] Actually, the biggest disadvantage of CAS is the difficulty of constructing the surrounding algorithms correctly.<br />
CAS performance varies widely across processors. On a single CPU system, a CAS typically takes on the order of a handful of clock cycles, since no synchronization across processors is necessary. As of this writing, the cost of an uncontended CAS on multiple CPU systems ranges from about ten to about 150 cycles; CAS performance is a rapidly moving target and varies not only across architectures but even across versions of the same processor. Competitive forces will likely result in continued CAS performance improvement over the next several years. A good rule of thumb is that the cost of the "fast path" for uncontended lock acquisition and release on most processors is approximately twice the cost of a CAS.<br />
<br />
15.2.3. CAS Support in the JVM<br />
------------------------------<br />
So, how does Java code convince the processor to execute a CAS on its behalf ?Prior to Java 5.0, there was no way to do this short of writing native code. In Java 5.0, low level support was added to expose CAS operations on int, long, and object references, and the JVM compiles these into the most efficient means provided by the underlying hardware. On platforms supporting CAS, the runtime inlines them into the appropriate machine instruction(s); in the worst case, if a CAS like instruction is not available the JVM uses a spin lock. This low level JVM support is used by the atomic variable classes (AtomicXXX in java.util.concurrent. atomic) to provide an efficient CAS operation on numeric and reference types; these atomic variable classes are used, directly or indirectly, to implement most of the classes in java.util.concurrent.<br />
<br />
Atomic Classes<br />
--------------<br />
AtomicInteger bears a superficial resemblance to an extended Counter class, but offers far<br />
greater scalability under contention because it can directly exploit underlying hardware support for concurrency.<br />
There are twelve atomic variable classes, divided into four groups: scalars, field updaters, arrays, and compound variables. The most commonly used atomic variables are the scalars: AtomicInteger, AtomicLong, AtomicBoolean, and AtomicReference. All support CAS; the Integer and Long versions support arithmetic as well. (To simulate atomic variables of other primitive types, you can cast short or byte values to and from int, and use floatToIntBits or doubleToLongBits for floating point numbers.)<br />
The atomic array classes (available in Integer, Long, and Reference versions) are arrays whose elements can be updated atomically. The atomic array classes provide volatile access semantics to the elements of the array, a feature not available for ordinary arrays a volatile array has volatile semantics only for the array reference, not for its elements. (The other types of atomic variables are discussed in Sections 15.4.3 and 15.4.4.)<br />
While the atomic scalar classes extend Number, they do not extend the primitive wrapper classes such as Integer or Long. In fact, they cannot: the primitive wrapper classes are immutable whereas the atomic variable classes are mutable. The atomic variable classes also do not redefine hashCode or equals; each instance is distinct. Like most mutable objects, they are not good candidates for keys in hash based collections.<br />
<br />
15.3.2. Performance Comparison: Locks Versus Atomic Variables<br />
-------------------------------------------------------------<br />
To demonstrate the differences in scalability between locks and atomic variables, we constructed a benchmark comparing several implementations of a pseudorandom number generator (PRNG). In a PRNG, the next "random" number is a deterministic function of the previous number, so a PRNG must remember the previous number as part of its state.<br />
Listings 15.4 and 15.5 show two implementations of a thread safe PRNG, one using ReentrantLock and the other using<br />
AtomicInteger. The test driver invokes each repeatedly; each iteration generates a random number (which fetches and<br />
modifies the shared seed state) and also performs a number of "busy work" iterations that operate strictly on thread<br />
local data. This simulates typical operations that include some portion of operating on shared state and some portion of operating on thread local state.<br />
Figures 15.1 and 15.2 show throughput with low and moderate levels of simulated work in each iteration. With a low<br />
level of thread local computation, the lock or atomic variable experiences heavy contention; with more thread local computation, the lock or atomic variable experiences less contention since it is accessed less often by each thread.<br />
<br />
15.4. Non blocking Algorithms<br />
-----------------------------<br />
Lock based algorithms are at risk for a number of liveness failures. If a thread holding a lock is delayed due to blocking I/O, page fault, or other delay, it is possible that no thread will make progress. An algorithm is called non blocking if failure or suspension of any thread cannot cause failure or suspension of another thread; an algorithm is called lock free if, at each step, some thread can make progress. Algorithms that use CAS exclusively for coordination between threads can, if constructed correctly, be both non blocking and lock free. An uncontended CAS always succeeds, and if multiple threads contend for a CAS, one always wins and therefore makes progress. Non blocking algorithms are also immune to deadlock or priority inversion (though they can exhibit starvation or livelock because they can involve repeated retries).<br />
We've seen one non blocking algorithm so far: CasCounter. Good non blocking algorithms are known for many common data structures, including stacks, queues, priority queues, and hash tables though designing new ones is a task best left to experts.<br />
<br />
15.4.2. A Non blocking Linked List<br />
----------------------------------<br />
The two non blocking algorithms we've seen so far, the counter and the stack, illustrate the basic pattern of using CAS to update a value speculatively, retrying if the update fails. The trick to building non blocking algorithms is to limit the scope of atomic changes to a single variable. With counters this is trivial, and with a stack it is straightforward enough, but for more complicated data structures such as queues, hash tables, or trees, it can get a lot trickier.<br />
<br />
15.4.3. Atomic Field Updaters<br />
-----------------------------<br />
Listing 15.7 illustrates the algorithm used by ConcurrentLinkedQueue, but the actual implementation is a bit different. Instead of representing each Node with an atomic reference, ConcurrentLinkedQueue uses an ordinary volatile reference and updates it through the reflection based AtomicReferenceFieldUpdater, as shown in Listing 15.8.<br />
<br />
Listing 15.8. Using Atomic Field Updaters in ConcurrentLinkedQueue.<br />
<br />
private class Node<e> {</e><br />
private final E item;<br />
private volatile Node<e> next;</e><br />
public Node(E item) {<br />
this.item = item;<br />
}<br />
}<br />
<br />
private static AtomicReferenceFieldUpdater<node, node=""> nextUpdater= AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "next");</node,><br />
<br />
The atomic field updater classes (available in Integer, Long, and Reference versions) represent a reflection based "view" of an existing volatile field so that CAS can be used on existing volatile fields. The updater classes have no constructors; to create one, you call the newUpdater factory method, specifying the class and field name. The field updater classes are not tied to a specific instance; one can be used to update the target field for any instance of the target class(Node a, b;). The atomicity guarantees for the updater classes are weaker than for the regular atomic classes because you cannot guarantee that the underlying fields will not be modified directly; the compareAndSet and arithmetic<br />
methods guarantee atomicity only with respect to other threads using the atomic field updater methods(some threads might use the Node instance directly to update). In ConcurrentLinkedQueue, updates to the next field of a Node are applied using the compareAndSet method of nextUpdater. This somewhat circuitous approach is used entirely for performance reasons. For frequently allocated, short lived objects like queue link nodes, eliminating the creation of an AtomicReference for each Node is significant enough to reduce the cost of insertion operations. However, in nearly all situations, ordinary atomic variables perform just fine in only a few cases will the atomic field updaters be needed. (The atomic field updaters are also useful when you want to perform atomic updates while preserving the serialized form of an existing class.)<br />
<br />
15.4.4. The ABA Problem<br />
-----------------------<br />
The ABA problem is an anomaly that can arise from the naive use of compare and swap in algorithms where nodes can<br />
be recycled (primarily in environments without garbage collection). A CAS effectively asks "Is the value of V still A?", and proceeds with the update if so. In most situations, including the examples presented in this chapter, this is entirely sufficient. However, sometimes we really want to ask "Has the value of V changed since I last observed it to be A?" For some algorithms, changing V from A to B and then back to A still counts as a change that requires us to retry some algorithmic step.<br />
This ABA problem can arise in algorithms that do their own memory management for link node objects. In this case, that the head of a list still refers to a previously observed node is not enough to imply that the contents of the list have not changed. If you cannot avoid the ABA problem by letting the garbage collector manage link nodes for you, there is still a relatively simple solution: instead of updating the value of a reference, update a pair of values, a reference and a version number. Even if the value changes from A to B and back to A, the version numbers will be different.<br />
AtomicStampedReference (and its cousin AtomicMarkableReference) provide atomic conditional update on a pair of<br />
variables. AtomicStampedReference updates an object reference integer pair, allowing "versioned" references that are<br />
immune[8] to the ABA problem. Similarly, AtomicMarkableReference updates an object reference boolean pair that is<br />
used by some algorithms to let a node remain in a list while being marked as deleted.[9]<br />
<br />
[8] In practice, anyway; theoretically the counter could wrap.<br />
[9] Many processors provide a double wide CAS (CAS2 or CASX) operation that can operate on a pointer integer pair, which would make this operation reasonably efficient. As of Java 6, Atomic-StampedReference does not use double wide CAS even on platforms that support it. (Double wide CAS differs from DCAS, which operates on two unrelated memory locations; as of this writing, no current processor implements DCAS.)<br />
<br />
16.1.3. The Java Memory Model in 500 Words or Less<br />
--------------------------------------------------<br />
The Java Memory Model is specified in terms of actions, which include reads and writes to variables, locks and unlocks of monitors, and starting and joining with threads. The JMM defines a partial ordering [2] called happens before on all actions within the program. To guarantee that the thread executing action B can see the results of action A (whether or not A and B occur in different threads), there must be a happens before relationship between A and B. In the absence of a happens before ordering between two operations, the JVM is free to reorder them as it pleases.<br />
<br />
The only order guarantees in JVM<br />
--------------------------------<br />
A data race occurs when a variable is read by more than one thread, and written by at least one thread, but the reads<br />
and writes are not ordered by happens before. A correctly synchronized program is one with no data races; correctly<br />
synchronized programs exhibit sequential consistency, meaning that all actions within the program appear to happen in<br />
a fixed, global order.<br />
The rules for happens before are:<br />
Program order rule. Each action in a thread happens before every action in that thread that comes later in the program order.<br />
Monitor lock rule. An unlock on a monitor lock happens before every subsequent lock on that same monitor lock.[3]<br />
Volatile variable rule. A write to a volatile field happens before every subsequent read of that same field.[4]<br />
Thread start rule. A call to Thread.start on a thread happens before every action in the started thread.<br />
Thread termination rule. Any action in a thread happens before any other thread detects that thread has terminated, either by successfully return from Thread.join or by Thread.isAlive returning false.<br />
Interruption rule. A thread calling interrupt on another thread happens before the interrupted thread detects the<br />
interrupt (either by having InterruptedException thrown, or invoking isInterrupted or interrupted).<br />
Finalizer rule. The end of a constructor for an object happens before the start of the finalizer for that object.<br />
Transitivity. If A happens before B, and B happens before C, then A happens before C.<br />
<br />
Other happens before orderings guaranteed by the class library include:<br />
Placing an item in a thread safe collection happens before another thread retrieves that item from the collection;<br />
Counting down on a CountDownLatch happens before a thread returns from await on that latch;<br />
Releasing a permit to a Semaphore happens before acquiring a permit from that same Semaphore;<br />
Actions taken by the task represented by a Future happens before another thread successfully returns from<br />
Future.get;<br />
Submitting a Runnable or Callable to an Executor happens before the task begins execution; and<br />
A thread arriving at a CyclicBarrier or Exchanger happens before the other threads are released from that<br />
same barrier or exchange point. If CyclicBarrier uses a barrier action, arriving at the barrier happens before<br />
the barrier action, which in turn happens before threads are released from the barrier.<br />
<br />
<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-72537720430339729552012-05-28T07:21:00.000+05:302012-07-17T23:17:45.365+05:30GIST NOTES 10 - Java Development<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: x-large;">GIST NOTES 10 - Java Development</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
[Java 7.0]<br />
<br />
Compiler<br />
========<br />
javac [options] [source files]<br />
<br />
<br />
-d option<br />
----------<br />
>destination folder to where .class files should go<br />
>compiler automatically can create package structure folders while creating .class files<br />
>the destination directory should exist in order for this command to succeed<br />
<br />
<br />
Running Java Application<br />
=========================<br />
<br />
java [options] class [args]<br />
<br />
<br />
java -DmyProp=myVal Myclass a b<br />
<br />
-D option is used to set system properties<br />
<br />
java.util.Properties can be obtained by System.getProperties() which contains general JVM/OS info, version info and along with it we can add our own user defined properties also to it (e.g. Properties p = System.getProperties(); p.setProperty("prop1","value1");<br />
<br />
The same thing is accomplished by -D option. When property value contains spaces, you should double quote it when setting it from command line.<br />
<br />
The following are valid:<br />
<br />
static public void main(String[] args)<br />
public static void main(String... s)<span class="Apple-tab-span" style="white-space: pre;"> </span>//valid from java 5<br />
static public void main(String hi_input_fellas[])<br />
<br />
searching for classes<br />
----------------------<br />
>both java and javac search the same way, same set of directories in the same order<br />
>first they search jdk standard directories<br />
>second in the directories defined by classpaths<br />
>classpath can be defined as OS environment variable or as an option to java/javac commands<br />
>command line classpaths override environment variable classpath<br />
>multiple class paths are separated by colon ( -classpath com/abc/hi:com/lexi )<br />
>in the above example it will not search com or com/abc<br />
>they don't search the current directory for .class files by default<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>-classpath ./com/hi:./com/lexi:.<br />
<br />
>however, javac will search current directory by default for .java files<br />
>in case of duplicate .class files, the file encountered first will be used<br />
>in the classpath search goes from left to right<br />
>option -classpath can be abbreviated to -cp<br />
<br />
Packages<br />
--------<br />
>fully qualified name of a class includes the entire package (com.murmur.tools.MyTool)<br />
>when we refer just 'MyTool' after importing the class, it is still an alias referring to com.murmur.tools.MyTool<br />
>classpath should always include the directory which contains the root package(top most package, e.g. com/)<br />
>jar -cf myjar.jar com -->creates the jar containing com directory available in the current directory<br />
>jar -tf myjar.jar -->unjars the jar in the current directory<br />
>java and javac will use a jar like a normal directory tree<br />
>jar files can be searched by including them in class path just like packages; jar file is considered as a directory containing the top-level package that is 'com'<br />
>when we say 'import java.util.*;' we only import classes under util package, but not other sub packages under util e.g. java.util.regex will not be imported<br />
>import statement can import only a single package at a time<br />
>java/javac search JDK/jre/lib/ext directory for any jars and include all of them into classpath automatically(should not be used in shipments of your application)<br />
><br />
<br />
Static Imports<br />
--------------<br />
>ability to import static variables<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>import static java.lang.Integer.*; //static import<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>import static java.lang.System.out; //static import<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>import java.util.*; //regular<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>...<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>...<br />
<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>out.println(MAX_VALUE); //instead of Integer.MAX_VALUE and System.out.println()<br />
<br />
<br />
>'static import' will not compile; it should be 'import static'<br />
>if static imports import same name from two different classes (Integer.MAX_VALUE and Long.MAX_VALUE), usage of such ambiguous variables cause compiler error<br />
>you can static import, constants, objects and methods which are static<br />
<br />
<b>Reference</b>: Kathy Sierra's SCJP Book<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-75269602487067591092012-05-27T07:18:00.000+05:302012-07-17T23:17:45.374+05:30GIST NOTES 9 - Java Threads<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: x-large;">GIST NOTES 9 - Java Threads</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
[Java 7.0]<br />
<br />
Light Weight Process -> LWPs are threads running on kernel threads; LWPs have tendency to share address space and resources with other LWPs inside a kernel thread; LWPs sit between user threads and kernel threads, that is one or more user threads are implemented on top of a single LWP<br />
<br />
Thread -> an instance of execution or thread of execution which runs on a CPU assuming that it is the only activity the processor is currently doing but in reality CPU time is given to thread partially. Threads share resources and address spaces with other threads inside a single Process<br />
<br />
Process -> Is a general user-specific application(though a single application can be made up of more than one process); a process has separate memory and resource which is not shared with any other processes; process has an objective and a task or activity to be completed; to finish its job it can employ many threads internally; e.g. text editor<br />
<br />
>an instance of Thread is just an object like any other<br />
>a thread of execution on the other hand is a separate process(light weight) that has its own call stack<br />
>in java there is one thread per call stack or one call stack per thread<br />
>everything runs in some threads even if you haven't explicitly created one<br />
>the main() method where the java application starts, actually runs on a thread called 'main' thread<br />
>any exception that comes up all the way up to main method and not handled there as well breaks the main thread the stack trace goes as follows:-<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Exception in thread "main" java.lang.Exception<br />
at MyClass.main(MyClass.java:5)<br />
<br />
>as soon as a new thread is created from main thread, call execution starts happening on a new stack separate from main's stack<br />
>call stacks of each thread run concurrently with each other<br />
>some JVMs map java threads onto OS threads (native threads)<br />
>some JVMs act as mini OS and schedule java threads on its own within the CPU cycles it bargains from the underlying OS<br />
>"when it comes to threads very little is guaranteed"<br />
>both you and operating system can create daemon threads<br />
>normal threads are called user threads<br />
>JVM doesn't wait for daemon threads to finish when it shuts down; JVM waits till all user threads complete and exit<br />
>daemon threads are kind of threads that run low on the background<br />
<br />
>To create a thread class either extend java.lang.Thread class or implement java.lang.Runnable; but to run the created thread we always need a java.lang.Thread instance<br />
<br />
>override public void run() method in your class (it is available both in Thread class as well as Runnable interface)<br />
>overloading run() method will not impact thread behavior; you are free to have as many overloaded run() methods as possible for fun<br />
>thread of execution only uses 'public void run()' method and no other<br />
>calling run() method directly doesn't start the thread<br />
>usually Thread instance is considered as 'worker' and Runnable implementer is considered as the 'job' to be done; so by implementing Runnable interface you keep the worker and the job separate from each other<br />
>Thread class also implements Runnable<br />
>when a thread object is created but not started yet, it is considered not alive yet<br />
>after calling start() method on the thread object, it is considered alive, but run() method may not have started executing yet<br />
>unless you are trying to improve java.lang.Thread don't extend it; instead use Runnable interface<br />
<br />
>a Runnable object can be reused in multiple threads to run<br />
>but a Thread object cannot be used multiple times to start threads; attempt to start() the thread more than once gives exception and that's why start() method itself is synchronized<br />
<br />
>after run() method completes, the thread is considered dead<br />
>isAlive() tells you whether a thread has completed or not<br />
>getState() returns enum constants(Thread.State) corresponding to the state of the thread<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Thread.State is a static nested enum<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>NEW - not yet started<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>RUNNABLE - is executing in JVM<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>BLOCKED - waiting for a monitor lock<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>WAITING - waiting indefinitely for another thread to complete a task<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>TIMED_WAITING - waiting for another thread upto a specified time<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>TERMINATED - thread has exited<br />
<br />
>before calling start(), the thread is in State.NEW state, after the call it moves to State.RUNNABLE state<br />
<br />
>some methods are static in Thread class (e.g. sleep() and yield()), because they control the currently running live threads<br />
>start(), setPriority() and such methods do not impact the running thread; they are merely setting up a Thread object which will be started as a new thread of execution soon<br />
>join() method is also NOT static; t.join() causes the currently executing thread to pause until thread t finishes<br />
>so any method which would control a live running thread has to be a STATIC method!<br />
>why sleep() method throws InterruptedException? sleep method allows a thread to sleep for a specified amount of time; if someone wakes it before the waiting time is finished, it throws exception and in the catch block you can do whatever you want knowing that the thread has woken up prematurely; if no one interrupted, then after the sleep time is over, the thread comes out of sleep state normally; the thread hangs at the Thread.sleep() statement until the time expires or someone interrupts; if no interrupts, the control moves to next statement when the sleep is over without any exceptions of course<br />
<br />
java.lang.Object class methods related to threads<br />
-------------------------------------------------<br />
public final void wait() throws InterruptedException<br />
public final void notify()<br />
public final void notifyAll()<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#only wait() method throws exception<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#all three methods are final methods; we can't override these blokes<br />
<br />
>t.join() method doesn't pause the currently running thread if t is already dead(TERMINATED) or not yet started(NEW)<br />
<br />
>to avoid data incosistency while concurrent threads are modifying the same data, we can either synchronize the methods that modify the data or use synchronized block around the critical code lines<br />
>synchornizing a method, uses the object on which the instance method is called as lock object; synchronized block allows any object to be used as lock<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public synchronized void modify(){//critical code} //the lock is the object on which modify() is invoked<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void modify(){<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//Object lock = new Object(); if this line is introduced, all threads can enter the synchronized block at the same time<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>synchronized(lock){ //the lock is any arbitrary object 'lock'<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//critical code goes here<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#when we use any arbitrary 'lock' object in synchronized blocks, make sure that only one instance of the lock is available to all threads; so usually a lock object should be an instance variable(if all threads are holding the same object containing modify() method), or final instance variable or static instance variable(if different threads holding different object that contains modify() method)<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#idea is never allow duplicate locks; a lock should be unique<br />
<br />
>only wait() method gives up the lock immediately<br />
>usually instance data modified by instance methods, static data is modified by static methods; by synchronizing those methods we can protect instance data(lock on that instance) and static data(lock on Class object of that class)<br />
>but what if a static data is modified by an instance method? even if the instance method is synchronized, it will not protect the data because any number of threads through different objects(each of them act as locks) can modify the same static data; so in this situation synchronizing the code using block sychronization and using Class object of the class as lock should fix the problem<br />
<br />
>same problem arises when a static method modifies a non-static data through one of the objects;<br />
>so to keep things simple and safe, always access static fields through static methods, non-static fields through non-static method and mark all those methods as synchronized<br />
<br />
>thread-safe classes are nothing but classes which protect their internal data by synchronizing their sensitive methods; when a thirdparty class uses a thread-safe class(like Vector or the one returned by Collections.synchronizedList()), it still can run into data inconsistency problems; because the thread safe class has synchronized individual methods; but the thirdparty class might use a sequence of method(synchronized ones) calls on the thread-safe class; those calls could be part of one atomic operation; that is they have to be done together or not at all; when the thirdparty's method(where the sequence happens) is not synchronized, multiple threads may try to execute the atomic(it is not atomic yet) operation simultaneously and two thirdparty sequences running at the same time can mess each other up;<br />
<br />
>so identify atomic operations in your code and synchronize the whole operation yourself even if the underlying data is thread-safe by itself; in such cases there is a redundant thread-safety which might hog the performance of your application; if possible remove the redundant thread-safety and put thread-safety always at higher level, by yourself<br />
<br />
>deadlock: two threads waiting for each others lock - to avoid always acquire locks in a predetermined order<br />
>press ctrl+break on the command prompt where java app is running to get a thread dump on deadlocked application; thread dump detects any existing deadlocks and displays; one can also see the monitor id each thread is holding and the monitor id they are waiting for; there can be two or more threads involved in a circular wait causing a deadlock;<br />
>symptom of a deadlock is unexpected long delay in certain synchronized tasks without apparent cause or Exceptions in the system<br />
<br />
Thread Dump<br />
-----------<br />
>displays all user threads and daemon threads in JVM<br />
>displays thread names, thread ids and their states<br />
>displays locks they are holding<br />
>displays stack information for deadlocked threads<br />
>displays Heap details(spaces like new generation, eden space, from space, to space, tenured generation, compacting perm gen, etc)<br />
<br />
Notes from Java Language Specification on Threads<br />
====================================<br />
>in java, synchronization is implemented using monitors<br />
>every object in java is associated with a monitor<br />
>only one thread can lock on a monitor of an object at a time<br />
>using volatile variables is a kind of synchronization<br />
>every object in addition to having a monitor also has an associated 'wait set'; wait set is a set of threads waiting for the monitor on that object; when the object is first created, the wait set is empty;<br />
>adding/removing threads from the wait set are atomic operations<br />
>wait sets are manipulated solely through wait(), notify() and notifyAll() methods<br />
>before or after Thread.sleep or Thread.yield, their cached variables are not flushed or updated or reloaded; that is they use the same copy of variables when they come back from sleep or runnable pool<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
For example, in the following (broken) code fragment, assume that this.done is a nonvolatile<br />
boolean field:<br />
<br />
while (!this.done)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Thread.sleep(1000);<br />
<br />
The compiler is free to read the field this.done just once, and reuse the cached value in each execution of the loop. This would mean that the loop would never terminate, even if another thread changed the value of this.done.<br />
---X---<br />
<br />
>if a thread calls obj.wait() (wait set for the object is already empty) and nobody calls notify() or the notify was sent before the call to wait(), then this thread will wait forever even if no other thread is using the lock of obj<br />
<br />
>a thread can come out of wait() only when someother thread issues notify() or it is interrupted<br />
<br />
>if a thread calls wait() on an object where no other thread is waiting for(wait set for the object is empty), then also the thread goes to waiting state<br />
<br />
>so whenever a thread gives up lock by calling wait(), it should check for valid conditions to wait(ensure there will be a notification in future for sure) or invoke timed wait(); and also do a recheck on the condition to continue when it wakes up from wait, because the notify might have been a wrong signal, or the thread wokeup spontaneously(occurs in some situations)<br />
<br />
>so keep your conditions to wait and conditions to continue, in check, before start waiting and start continuing respectively<br />
<br />
>Calling wait() outside synchronized code will not cause compilation error, but might cause runtime error(IllegalMonitorStateException)<br />
<br />
>synchronization is a tricky business; while overriding a synchronized method, the overrider may choose to eliminate synchronized in its implementation and open the gate of hell; but still to access the parent version of the method in that subclass object, threads should go through lock acquisition<br />
<br />
<b>Reference</b>: Kathy Sierra's SCJP Book<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0Chennai, Tamil Nadu, India13.060422 80.24958312.936679000000002 80.0916545 13.184165 80.4075115tag:blogger.com,1999:blog-5659366926389737478.post-71530841714895263952012-05-26T07:15:00.000+05:302012-07-17T23:17:45.357+05:30GIST NOTES 8 - Java Inner Classes<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: x-large;">GIST NOTES 8 - Java Inner Classes</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
[JDK 7]<br />
<br />
>Inner classes have powerful and efficient uses in specific situations<br />
>produce code easier to read and maintain<br />
>over use of inner classes lead to complex code leading to a syndrome known as "reuseless": code that's useless over and over again<br />
>inner classes allow to define classes within classes<br />
>type of scoping for inner classes is provided when we make one class as a member of another class<br />
>static inner class is called "top level nested class" is not really an inner class, but a class in itself defined within the scope of another class<br />
>when you need a separate class for a job and still need it to be intimately connected to your main class, we go for inner classes; e.g. event handlers; they are one of the main reasons inner classes were added to the language<br />
>the intimacy is needed because, event handlers for example need to access text content on the GUI component directly when user events occur; that means event handlers need access to the members of the GUI classes<br />
>especially the situation gets even clear to separate event handler from main classes is when both of them need to extend from different classes/parents(multiple inheritance not possible); so we are better off not combining those two classes<br />
>it even gets clearer when the event handler needs to access the private members of the main class(making those members public and exposing is not a good OO design and will lead to problems)<br />
<br />
>this is where main class and inner class create a special relationship with each other; this relationship is shared between one inner class intance and one instance of outer class, as if inner class is part of outer class(it really is)<br />
<br />
>inner class can access everything that is of outer class(this is not a violation of encapsulation because, whoever writes outer class also writes the inner class and they share the same class space; and the privileges given to inner class is not available to anyone else in the OO world)<br />
<br />
>four types of inner classes: 1.inner classes(regular) 2.static 3. method-local 4.anonymous<br />
<br />
Inner classes<br />
-------------<br />
>we define it within the curly braces of the outer class<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class Outer{<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class Inner{}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
>since inner class is a separate class, compiler generates a separate file for it (Outer$Inner.class)<br />
>but directly running the inner class from command prompt would require main method in Inner class, and no static keyword of anykind is allowed inside the Inner class definition because it is tied to a live instance of the Outer class. Hence, no one can run the Inner class<br />
>when you decompile Outer$Inner.class you get something like the following:-<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
class Outer$Inner<br />
{<br />
<br />
final Outer this$0;<br />
<br />
Outer$Inner()<br />
{<br />
this$0 = Outer.this;<br />
super();<br />
}<br />
}<br />
<br />
#don't be fooled by 'this$0'; it is just a regular identifier; point is, compiler puts a final variable holding an instance of Outer class inside the Inner class<br />
<br />
>only way to access an inner class is through a live instance of outer class; inner class doesn't exist until an outer class instance gets created in the JVM<br />
<br />
>just like an instance method can access the private variables, inner classes also can access the private variables of the outer class; inner class is a valid member of(instance member as well) outer class<br />
<br />
Instantiating Inner Class<br />
-------------------------<br />
To create an instance of inner class, you must have an instance of the outer class to tie to the inner class. There is no exception to this rule. An inner class instance can never stand alone without a direct relationship to an instance of the outer class<br />
<br />
>"new Inner()" is considered (instantiating inner class) as a non-static variable and cannot be performed within static context; for example, the main method of outer class cannot instantiate Inner class, or any other static method or static block for that matter; only constructors or instance methods of Outer class can instantiate Inner class<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class Outer{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>void create(){<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Inner in = new Inner(); //legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public static void main(String[] args){<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Inner in1 = new Inner(); //illegal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Inner in2 = new Outer().new Inner(); //legal - but not possible outside Outer class<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
>considering the above rule, there is a way to instantiate Inner within a static context or outside of Outer class<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Outer outer = new Outer();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Outer.Inner a1 = outer.new Inner();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Outer.Inner a2 = outer.(new Inner()); //illegal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Outer.Inner a3 = new Outer().new Inner();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Outer.Inner a4 = new Outer().(new Inner()); //illegal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Outer.Inner a5 = (new Outer()).(new Inner()); //illegal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Outer.Inner a6 = (outer).new Inner();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Outer.Inner a7 = (new Outer()).new Inner();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#don't bracket the Inner constructor call; new operator should follow the dot<br />
<br />
Within Inner<br />
------------<br />
>to refer Inner instance use 'this'<br />
>to refer Outer instance to whom inner instance is tied to, use 'Outer.this'<br />
<br />
Modifiers applicable to Inner class declaration (as a member of Outer class)<br />
----------------------------------------------------------------------------<br />
final<br />
abstract<br />
public<br />
private<br />
protected<br />
static (Inner is no longer an inner class; it becomes nested class)<br />
strictfp<br />
<br />
Method Local Inner Classes<br />
==========================<br />
>inner class defined within a method; instantiated like a regular class within the same method but only after its definition<br />
>it can only access final variables of the method(variables declared final within the method)<br />
>it can access all members of Outer class<br />
>it can instantiate other inner classes of Outer class directly<br />
>it can refer itself with 'this' and Outer class with 'Outer.this' but cannot refer any other non-enclosing inner classes of Outer with 'this' keyword<br />
>method-local inner class can again nested within another method local inner class<br />
>modifiers applicable to method-local-inner class declarations: final, abstract and strictfp<br />
>public, private, protected, transient and static modifiers are not allowed<br />
>same rule goes for all nested inner classes of method-local-inner-class; classes within method-local-inner-class can have only final, abstract or strictfp modifiers (this is just like for any variable within a method)<br />
>inner classes within method-local-inner classes can have again inner classes within their methods and so on to any number of levels<br />
>inner classes within method-local-inner classes can have regular inner classes as well<br />
>unless you are crazy, you can stop at one method-local-inner class :-)<br />
<br />
>method local inner classes can only be instantiated and used within that method itself and not anywhere anywhere at all<br />
>method local inner classes cannot access method local variables(except for final variables), because, those variables only live in stack; their lifetime is only during the execution of the method on the stack; but method-local-inner class instance can still stick around in the heap even after the completion of the said method; at that state method local variables no longer exist but inner class object is still functioning; so this rule;<br />
<br />
>on the side note, volatile is applicable for instance variables(of all types of classes and inner classes) only; cannot be used for method local variables<br />
<br />
>suppose if you put your inner class inside a static method, what happens: this inner class can access only static members of the enclosing class; cannot use 'this' operator; no access to any instance members; same restriction as for static methods applies to this inner class as well<br />
<br />
Anonymous Inner Classes<br />
-----------------------<br />
>We love them; they come handy when you are coding swing GUI application and need quick event listeners<br />
>anonymous inner classes have no name; they can be defined anywhere you can run any statement(constructors, blocks, methods); even inside method call argument list<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class Outer {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>private Parent p = new Parent() {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void displayName() {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(this.getClass().getName());<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void myOwnMethod(){}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>};<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#inner class was created in the assignment statement of the instance variable of Outer class<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#inner class has no name, but extends from Parent class and overrides displayName() method<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#variable p holds an instance of this anonymous subclass of Parent class<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#calling p.displayName() will run the overridden version of the method;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#it displays the random name given by the compiler to our anonymous inner class(something like Outer$1)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#anonymous class definition must end with semicolon to keep the assignment statement intact<br />
<br />
>since the anonymous instance is held in the parent class reference variable, we cannot call methods specific to the anonymous instance<br />
>though the anonymous class is free to define its own methods and use them inside, no one can access them and there is no means to reach them by anyone because nobody knows the name of the new class<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
>in the above example, we can't say p.myOwnMethod()<br />
<br />
>we can make an anonymous inner class to implement an interface instead of extending/subclassing a class<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Runnable newGuy = new Runnable() {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void run(){}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>};<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#here, we know that Runnable is an interface, and we created a concrete runnable class which has no name;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#this looks like instantiating an interface, but it is not<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#and we can implement only one interface like this; no way an anonymous inner class can implement multiple interfaces<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#or extending one class and implementing one interface at the same time is also not possible<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
>basically usage of 'implements' or 'extends' keywords is forbidden for anonymous inner classes<br />
>inner classes within method argument list<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public static void processThread( new Runnable(){ public void run(){} } );//is a single statement<br />
<br />
Static Nested Classes<br />
----------------------<br />
>these are referred to as 'static inner classes'<br />
>these are really not inner classes according to the standard definition of inner classes<br />
>while a real inner class has a special relationship with outer class instance, a static inner class or static nested class does not have that relationship with outer class instance<br />
>with static nested classes, it is really about namespace resolution than about an implicit relationship between two classes<br />
>it is just a top-level or regular class scoped within another class<br />
>it is also a static member of the enclosing class<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class Outer {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>static class Nested {}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
>Nested itself isn't really static; there is no such thing as static classes; it just means that Nested will be a static member of Outer and can be accessed like any other static members; that is without the need for any instances of Outer class to access it<br />
>static nested class cannot access any instance members of the enclosing class, but can access other static members<br />
>it can be instantiated anywhere(in the enclosing class or a thirdparty class) as follows<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>File 1:<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class Outer {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>private static String name = "doggy";<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>private String desc = "";<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>static class Inner {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void display() {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(name); //legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(desc); //illegal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(this); //legal - Inner is still a class of its own<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(Outer.this); //illegal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>new Inner(); //legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>private void hi() {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Inner in = new Inner(); //legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public static void main(String[] args) {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Inner in = new Inner(); //legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>static{ Inner in = new Inner(); } //legal static block<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{ Inner in = new Inner(); } //legal non-static block<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>File 2:<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class ThirdParty {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>hello() {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Outer.Inner in = new Outer.Inner(); // legal - one 'new' and a pair of parentheses are missing<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//from the syntax of regular inner class instantiation<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Inner in = new Inner(); //illegal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<div>
<br /></div>
<div>
<b>Reference</b>: Kathy Sierra's SCJP Book</div>
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-31789738636980943122012-05-25T07:11:00.000+05:302012-07-17T23:17:45.316+05:30GIST NOTES 7 - Java Generics and Collections<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: x-large;">GIST NOTES 7 - Java Generics and Collections</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
[JDK 7]<br />
<br />
> Object.equals() uses == operator to compare two objects. It just compares the two references refer to the same object or not<br />
<br />
public boolean equals(Object obj) {<br />
return (this == obj);<br />
}<br />
<br />
> trying to narrow the access level while overriding a method causes compilation error (be wary when overriding equals() method)<br />
<br />
equals() contract<br />
-----------------<br />
Reflexive: x.equals(x) returns true<br />
Symmetric: if x.equals(y) true, then y.equals(x) should be true<br />
Transitive: if x.equals(y) and y.equals(z) are true, then x.equals(z) also true<br />
Consistent: equals() method should be consistent always within a JVM for a given pair of objects no matter how many times equals() method is called<br />
<br />
null equality: for any non-null x, x.equals(null) should be false<br />
<br />
hashCode() compatibility: honor the hashCode() method while implementing equals()<br />
<br />
hashcode<br />
--------<br />
public int hashCode() is a native method in Object class.<br />
<br />
Hashcodes are typically used to increase the performance of large collections of data.<br />
<br />
Hashcode need not be unique to a particular object.<br />
<br />
If two objects are considered equal, then their hashCode also should be equal in order for java Collections framework to work consistently with your class objects. Java Collections framework uses hashcode of the object to distribute keys across different buckets. If hashcode is not consistent, your class objects may be lost forever in Collections classes(e.g. HashMap).<br />
<br />
hashCode() contract<br />
-------------------<br />
>whenever hashCode() is invoked on the same object more than once during an execution of a java application it must return the same value unless otherwise the information used in equals() comaparison has changed; during another execution of the same application it can return a different value<br />
<br />
>if two objects are equal according to equals() method, then hashCode() method should produce same integer for both objects<br />
<br />
>if two objects are different according to equals(), then it is not required for hashCode() to return different hash codes; however producing different hash code for unequal objects would improve the performance of the hashtables<br />
<br />
>if hash codes are different for two objects, then they cannot and should not be equal; equals() method should uphold this<br />
<br />
>transient variables should not be used in hashCode() implementation; though compiler will not complain, it might cause problems while trying to locate your object in collections; since transient variables are not saved while serializing, the restored object may not be the same and might break hashCode() implementation; same goes for equals() method; say NO to transient variables while implementing these two methods<br />
<br />
The core collections interfaces<br />
-------------------------------<br />
Collection<br />
List<br />
Queue<br />
<br />
Set<br />
Map<br />
<br />
NavigableSet<br />
NavigableMap<br />
SortedSet<br />
SortedMap<br />
<br />
The core concrete Classes<br />
-------------------------<br />
Maps:: HashMap, Hashtable, TreeMap, LinkedHashMap<br />
Sets:: HashSet, LinkedHashSet, TreeSet<br />
Lists:: ArrayList, Vector, LinkedList<br />
Queues:: PriorityQueue<br />
Utilities:: Collections, Arrays<br />
<br />
>not all collections in collection framework implement "Collection" interface<br />
>none of the map related interfaces and classes extend from "Collection" interface, though they are thought of as collections<br />
<br />
1.collection - represents general data structures<br />
2.Collection - represents java.util.Collection interface (Set, List and Queue extend from this);<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> there are no direct implementation of Collection interface;<br />
3.Collections - represents java.util.Collections concrete class which has loads of static utility methods<br />
<br />
<br />
Class Hierarchy (refer the image)<br />
---------------<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0lakRiXC6h4P-AW9CQQbbI94NytXgxTfRTeysuIeaQaqtwNUvO28q6S-VGoatSwJ0H77CAPK5A27h-nXUCGgc2Ea0ygGRhTYkTnO2rINxq-QHNhB0FsMCX3aWxSBVLW_3vyiNdUYWRX0y/s1600/Collections+Class+Hierarchy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0lakRiXC6h4P-AW9CQQbbI94NytXgxTfRTeysuIeaQaqtwNUvO28q6S-VGoatSwJ0H77CAPK5A27h-nXUCGgc2Ea0ygGRhTYkTnO2rINxq-QHNhB0FsMCX3aWxSBVLW_3vyiNdUYWRX0y/s320/Collections+Class+Hierarchy.png" width="320" /></a></div>
<br />
I:Collection <- I:Set <- HashSet <- LinkedHashSet<br />
I:Collection <- I:Set <- I:SortedSet <- I:NavigableSet <- TreeSet**<br />
<br />
I:Collection <- I:List <- ArrayList/Vector/LinkedList*<br />
I:Collection <- I:Queue <- PrioriotyQueue/LinkedList<br />
<br />
I:Map <- Hashtable<br />
I:Map <- HashMap <- LinkedHashMap<br />
I:Map <- I:SortedMap <- I:NavigableMap <- TreeMap<br />
<br />
[Interfaces start with 'I:' and parents come on the left hand side, children on the right]<br />
<br />
* LinkedList is both a Queue as well as a List<br />
** Tree things(which has tree in the name) are both navigable and sorted<br />
*** Those that are unordered by nature(map and set), given Tree status<br />
<br />
Collection Flavors<br />
------------------<br />
List - list of things<br />
Set - bunch of unique things<br />
Map - things with unique ID<br />
Queue - things arranged in order<br />
<br />
Sub-Flavors<br />
------------<br />
>A class can be 'unsorted and unordered'<br />
>A class can be 'ordered but unsorted'<br />
>A class can be 'ordered and sorted'<br />
>A class can NEVER be 'sorted but unordered', because sorting is a specific type of ordering inherently<br />
<br />
Sorting:: order in the collection is based on the natural order of elements, based on some rules known as sort order<br />
<br />
HashSet - unordered and unsorted<br />
LinkedHashSet - ordered but not sorted(ordered by addition)<br />
Hashtable - unordered and unsorted (when iterating over, the order is random)<br />
ArrayList - ordered but not sorted (ordered by position index, can insert anywhere)<br />
LinkedHashSet - ordered but not sorted(ordered by addition)<br />
<br />
List<br />
====<br />
>cares about index<br />
>index related methods like get(int index) are available only in List based classes<br />
>lists are ordered by index position<br />
>can add elements at a particular index or at the end of the list<br />
<br />
ArrayList<br />
----------<br />
>growable array<br />
>gives fast iteration and fast random access<br />
>ordered but not sorted<br />
>implements RandomAccess interface(marker interface), hence ArrayList supports fast(generally constant time) random access<br />
>choose this over LinkedList when you need fast iteration but aren't as likely to be doing a lot of insertion and deletion<br />
>methods are not synchronized<br />
<br />
Vector<br />
------<br />
>holdover from earliest days of java; Vector and Hashtable were the original collections (rest were added at 1.2 and 1.4)<br />
>same as ArrayList but methods are synchronized for thread safety<br />
>due to synchronized, Vector is slow in performance<br />
>thread safety can be obtained from Collections utility methods as well instead of using Vector<br />
>Vector is the only class other than ArrayList to implement RandomAccess<br />
<br />
LinkedList<br />
----------<br />
>is ordered by index position(like ArrayList), except that elements are doubly-linked to one another<br />
>methods to add/remove from beginning or end<br />
>easy choice to implement stack or queue<br />
>iterates more slowly than ArrayList<br />
>but a good choice for fast insertion and deletion<br />
>as of java 5, it was enhanced to implement Queue interface as well; hence supports peek(), poll(), offer() and such methods<br />
<br />
Set<br />
===<br />
>cares about uniqueness<br />
>doesn't allow duplicates<br />
>bases itself on equals() method implementation<br />
<br />
HashSet<br />
-------<br />
>unsorted and unordered set<br />
>uses hashcode of the object being inserted; the more efficient hashCode() implementation, the better access performance<br />
>use this when you want no duplicates and don't care about order when you iterate through the elements<br />
<br />
LinkedHashSet<br />
-------------<br />
>an ordered version of HashSet<br />
>maintains doubly-linked list across all elements<br />
>if you care about iteration order, use this<br />
>it lets you iterate through in the order in which elements were inserted(or added)<br />
<br />
# when using HashSet or LinkedHashSet, you must override hashCode(), otherwise uniqueness of objects is not guaranteed<br />
<br />
TreeSet<br />
-------<br />
>is one of the two sorted collections (the other being TreeMap)<br />
>uses Red-Black tree structure(special binary search tree with minimum possible height)<br />
>guarantees that the elements will be in ascending order according to natural order<br />
>lets you specify your own ordering rules by using Comparable or Comparator<br />
>as of java 6, TreeSet also implements NavigableSet<br />
<br />
Map<br />
===<br />
>cares about unique identifiers for each value<br />
>both key and value are objects<br />
>relies on equals() to determine two keys are same or not<br />
<br />
HashMap<br />
-------<br />
>unsorted unordered map<br />
>access performance depends on the hashCode() implementation for your keys<br />
>allows one null key and multiple null values<br />
<br />
Hashtable<br />
---------<br />
>legacy class<br />
>synchronized counter part to HashMap<br />
>doesn't allow null keys or values(throws NullPointerException in such cases)<br />
<br />
LinkedHashMap<br />
-------------<br />
>maintains insertion order(optionally access order, thru a flag to the constructor)<br />
>slower than HashMap for adding removing elements<br />
>faster iteration than HashMap<br />
<br />
TreeMap<br />
-------<br />
>sorted Map and hence ordered in the natural order<br />
>lets you define custom sort order through Comparable or Comparator interfaces<br />
>as of java 6, implements NavigableMap<br />
<br />
Queue<br />
=====<br />
>list of TO-DOs<br />
>typically thought of as FIFO(first-in first-out)<br />
>supports standard Collection methods + methods to add/subtract/review queue elements<br />
<br />
PriorityQueue<br />
-------------<br />
>new with Java 5<br />
>basic queues can be implemented with LinkedList<br />
>purpose of PriorityQueue is to create "priority-in priority-out" queue as opposed to "first-in first-out)<br />
>elements are ordered according to natural order or according to the Comparator set<br />
>elements that are sorted first are accessed first; ordering represents the relative priority between elements<br />
<br />
ArrayList over arrays<br />
---------------------<br />
>ArrayList can grow dynamically<br />
>it provides more powerful insertion and search mechanisms than arrays<br />
>if there are duplicate elements in ArrayList, and when you try to remove an element, it removes the first encountered element that satisfies equals() method<br />
>be vary of remove(Object o) and remove(int index) overloaded methods getting confused when you use autoboxing for an array list of Integer type (ArrayList<integer>); e.g. if you try to remove element 54 with remove(54), it tries to remove element at index 54 rather than an Integer object with value 54; if you are lucky you will get index out of bounds exception if index 54 is not present; remove(new Integer(54)) works fine</integer><br />
<br />
>when you override equals() method you always take 'Object type' argument because the method is inherited from Object class<br />
>but when you implement compareTo() method from Comparable interface, you should take 'argument of the type of the object you are comparing' because Comparable interface supports generics and it lets you specify the type of the thing being compared before hand<br />
<br />
equals(Object o){}<br />
compareTo(MyDvd dvd){}<br />
<br />
>to sort a class objects in multiple different ways without getting stuck with one implementation of Comparable interface, go for Comparator where the rule of comparing is stored externally in your own Comparator class and you can make any number of different Comparator classes and use them wherever appropriate<br />
<br />
>you can even sort classes which you can't modify using this external Comparator<br />
<br />
Comparable<br />
----------<br />
>java.lang.Comparable<br />
>int obj1.compareTo(obj2)<br />
>returns negative int when obj2 is greater, positive int when obj1 is greater, zero when both are equal<br />
>you must modify the class whose instances you want to sort<br />
>only one sort sequence can be done<br />
>implemented frequently by APIs such as String, Wrapper classes, Date, Calendar, etc<br />
<br />
Comparator<br />
----------<br />
>java.util.Comparator<br />
>int compare(obj1, obj2)<br />
>return value is same as Comparable<br />
>you build a class separate from the class whose instances you want to sort<br />
>many sort sequences can be created<br />
>meant to be implemented by third party classes<br />
<br />
*both Comparable and Comparator are interfaces; they are appropriately put in different packages based on their purpose<br />
<br />
# Arrays.sort() provides sorting capability for arrays in the same way Collections.sort() provides<br />
<br />
Sorting arrays<br />
--------------<br />
>Arrays.sort(arrayToSort[])<br />
>Arrays.sort(arrayToSort[], Comparator)<br />
>loads of sort() overloaded methods to sort primitive data arrays in their natural order without the use of Comparator<br />
<br />
#both Arrays.sort() and Collections.sort() are static methods; both alter the same object they are sorting and do not return result as a separate object;<br />
<br />
#if two objects that are not comparable present in the array or collection, the sort will fail<br />
<br />
Searching arrays and collections<br />
--------------------------------<br />
>searches are performed using the binarySearch() method<br />
>successful search returns the int index of the element searched<br />
>unsuccessful search returns insertion point(index) as return value; insertion point is where the searched element can be added without affecting the sorted order of other elements<br />
>0 and positive return values indicate successful search<br />
>negative return value indicates insertion point on unsuccessful search<br />
>since 0 is not available for negative range, -1 indicates 0th index, -2 indicates 1st index and so on; so insertion point is calculated by [-n -1] where n is the signed insertion index returned.<br />
<br />
>the collection/array being searched must be sorted before you can search it<br />
>attempting to search an unsorted array or collection will result in unpredictable results(not compiler error :))<br />
>the collection/array sorted in natural order can only be searched in natural order using binarySearch() method; hence no Comparator is allowed<br />
>comparators cannot be used while searching arrays of primitives(nobody wants your own way of arranging integers, strings, etc)<br />
>the same comparator used to sort has to be used while searching; otherwise the consequences are dire<br />
>even trying to search an array or collection that has been reverse-sorted(descending) will return incorrect result<br />
<br />
SEARCH RULE--> SORT : SAME_COMPARATOR : ASCENDING<br />
<br />
Collection to Arrays<br />
--------------------<br />
List and Set have toArray() methods to convert the collection into an array(returns a copy of the internal array)<br />
<br />
Arrays to Collection<br />
--------------------<br />
Arrays.asList() copies an array into a List; this list is backed by the original array; changes to the returned list write through to the array; that is changing either the array or the list, updates the other automatically; array and list both become joined at the hip;(makes the given array as the internal array for the new list)<br />
<br />
> list.toArray() can return a new array or you can pass your own destination array list.toArray(dest[])<br />
<br />
Lists and Iterators<br />
--------------------<br />
list.iterator() returns an Iterator object;<br />
<br />
Iterator methods: boolean hasNext() and Object next()<br />
<br />
Sets<br />
----<br />
>no duplicates are allowed<br />
>adding duplicate object, add() method returns false without adding the object to the set<br />
>HashSet is fast because it uses hashcodes<br />
>TreeSet keeps the unique objects sorted; adding uncomparable objects to a TreeSet throws ClassCastException; e.g. adding String to an integer TreeSet<integer></integer><br />
<br />
Maps<br />
-----<br />
>Class of objects used as keys in map, should override equals() and hashCode() methods for the map to work properly at runtime<br />
>enums can be used as keys in maps; because enum overrides equals() and hashCode() methods<br />
>if the object that is used as key is modified after using it in the map, then retrieval of the corresponding value for that key will fail because the attributes used by equals() method could have been modified in that object<br />
<br />
Navigating TreeSet and TreeMap<br />
------------------------------<br />
>Since TreeSet and TreeMap are sorted in nature, Java 6 added NavigableMap and NavigableSet interfaces to their behavior in order to make arbitrary searching or navigation a lot easier than before<br />
>before Java 6, headSet(), tailSet(), first() and last() methods were used to navigate TreeSet and methods like headMap(), tailMap(), firstKey() and lastKey() were used to navigate TreeMap<br />
>now, more modern and easy to use methods are provided for navigation by NavigableSet and NavigableMap interfaces<br />
<br />
Methods from SortedSet and SortedMap interfaces<br />
------------------------------------------------<br />
headSet(item)/headMap(item) -> returns the portion of the set/map which is strictly less than 'item'; the sub set/map is tied to the original one; modifying one will update the other automatically; item is key in case of Map<br />
<br />
tailSet(item)/tailMap(item) -> returns the portion strictly higher than 'item'<br />
<br />
first()/firstKey() -> returns the first element(lowest) in the current set/map<br />
<br />
last()/lastKey() -> returns the last element(highest) in the current set/map<br />
<br />
subSet(fromVal,toVal)/subMap(fromVal,toVal) -> returns the portion of the set/map from value 'fromVal' (inclusive) to value 'toVal' (exclusive)<br />
<br />
Methods from NavigableSet and NavigableMap interfaces<br />
-----------------------------------------------------<br />
From NavigableSet:-<br />
<br />
TreeSet.ceiling(e) - returns lowest possible element >= e (nothing but returning the next value to e or e itself)<br />
TreeSet.higher(e) - returns lowest possible element > e (returns next value to e)<br />
TreeSet.floor(e) - returns highest possible element <= e (returns previous value to e or e itself)<br />
TreeSet.lower(e) - returns highest possible element < e (returns previous value to e)<br />
TreeSet.pollFirst() - removes and returns the first element<br />
TreeSet.pollLast() - removes and returns the last element<br />
TreeSet.descendingSet() - returns a NavigableSet in reverse order<br />
<br />
From NavigableMap:-<br />
<br />
TreeMap.ceilingKey(k) - returns lowest possible key >= k (same as TreeSet)<br />
TreeMap.higherKey(k) - returns lowest possible key > k (-do-)<br />
TreeMap.floorKey(k) - returns highest possible key <= k<br />
TreeMap.lowerKey(k) - returns highest possible key < k<br />
TreeMap.pollFirstEntry() - returns first key-value pair<br />
TreeMap.pollLastEntry() - returns last key-value pair<br />
TreeMap.descendingMap() - returns a NavigableMap in reverse order<br />
<br />
* all the subsets or submaps returned in above methods are backed by the original set or map; when you add a new element to the original set/map, the subset/submap also gets updated as well(as long as the new element satisfies the condition to be part of the submap), not just the one way<br />
<br />
* such behavior is called "backed collections"<br />
<br />
* any attempt to add out of range element to a subset or submap, it throws exception<br />
<br />
Inclusivity of subsets or submaps<br />
---------------------------------<br />
headSet(element, boolean isInclusive)<br />
headSet(element) -----behaves like-----> headSet(element, false)<br />
<br />
tailSet(element, boolean isInclusive)<br />
tailSet(element) ------behaves like------> tailSet(element, true)<br />
<br />
subSet(fromEle, boolean isFromInclusive, toEle, boolean isToInclusive)<br />
subSet(fromEle, toEle) ------behaves like------> subSet(fromEle, true, toEle, false)<br />
<br />
*overloaded methods with isInclusive boolean argument are from NavigableSet interface; their normal counter parts are from SortedSet<br />
*methods without isInclusive bool argument include starting point element as a rule<br />
*the above inclusivity discussion applies to headMap(), tailMap() and subMap() methods from TreeMap in the similar manner<br />
*methods without bool argument return SortedSet or SortedMap(old interfaces - before Java 6)<br />
*methods with bool argument return NavigableSet or NavigableMap(interfaces that are new to Java 6)<br />
*pollFirst/pollLast/pollFirstEntry and such polling methods are available only in Navigable[Set/Map]<br />
*while creating sub sets or maps(using methods with bool arg), be sure to assign them to Navigable[Set/Map] variable; can't be assigned to Sorted[Set/Map] variable or Tree[Set/Map] variables; using methods without bool arg returns Sorted[Set/Map] and they don't have polling methods; so if you want to do some polling, you have to use methods with bool arg only<br />
*polling either on parent set/map or sub set/map removes that element from both parent as well as the sub set/map if that element is present in both; so polling on sub set always affects the parent, but polling on parent may not affect the sub set because that element may not present in the sub set/map so no updates there<br />
<br />
PriorityQueue<br />
-------------<br />
>orders elements using a user-defined priority<br />
>can be a natural ordering (1 is higher priority than 2)<br />
>priority can be ordered through a Comparator also that lets you define your own ordering<br />
>Queue specific methods are peek(), poll() and offer()<br />
>PriorityQueue uses natural ordering or a given Comparator to prioritize<br />
<br />
peek() - returns top element without removing it from the queue<br />
poll() - returns top element and removes it from the queue<br />
offer() - puts the element into the queue according to its priority; top priority item goes to the top of the queue, least priority item goes to the end of the queue<br />
<br />
java.util.Arrays<br />
----------------<br />
static List asList(T[])<br />
<br />
static int binarySearch(Object[], key) - search or detect insertion point<br />
static int binarySearch(primitive[], key)<br />
static int binarySearch(T[], key, Comparator)<br />
<br />
static boolean equals(Object[], Object[])<br />
static boolean equals(primitive[], primitive[])<br />
<br />
public static void sort(Object[])<br />
public static void sort(primitive[])<br />
public static void sort(T[], Comparator)<br />
<br />
public static String toString(Object[])<br />
public static String toString(primitive[])<br />
<br />
java.util.Collections<br />
---------------------<br />
static int binarySearch(List, key)<br />
static int binarySearch(List, key, Comparator)<br />
<br />
static void reverse(List)<br />
static Comparator reverseOrder() - reverse comparator for all Comparable objects<br />
static Comparator reverseOrder(Comparator) - reverse comparator for the given Comparator<br />
<br />
static void sort(List)<br />
static void sort(List, Comparator)<br />
<br />
List, Set and Map methods<br />
-------------------------<br />
boolean add(element) -> List/Set<br />
boolean add(index, element) -> List<br />
<br />
boolean contains(Object) -> List/Set<br />
boolean containsKey(Object key) -> Map<br />
boolean containsValue(Object value) -> Map<br />
<br />
Object get(index) -> List<br />
Object get(key) -> Map<br />
<br />
int indexOf(Object) -> List<br />
<br />
Iterator iterator() -> List/Set<br />
<br />
Set keySet() -> Map<br />
<br />
put(key,value) -> Map<br />
<br />
remove(index) -> List<br />
remove(Object) -> List/Set<br />
remove(key) -> Map<br />
<br />
int size() -> List/Set/Map<br />
<br />
Object[] toArray() -> List/Set<br />
T[] toArray(T[]) -> List/Set<br />
<br />
String natural order<br />
--------------------<br />
>space comes before letters<br />
>uppercase letters come before lowercase letters<br />
>e.g. " f", "FF", "f ", "ff" are alphabetically sorted<br />
<br />
Iterator/Enumeration/ConcurrentModificationException<br />
----------------------------------------------------<br />
Iterator - provided by all collections; helps to navigate the collection; Iterator also provides method to remove an element; more modern than Enumeration; throws ConcurrentModificationException when somebody else directly modified the collection while we are trying to modify the same collection through Iterator; has shorter method names than Enumeration[hasNext(), next() and remove()]<br />
<br />
Enumeration - Some of the collections provide Enumeration to iterate over the collection; older version; does not provide facility to remove elements from the collection; since it doesn't modify the collection underneath, there is no need for ConcurrentModificationException<br />
<br />
ConcurrentModificationException - it is a failfast feature on a best effort basis; rather than continuing to function under erraneous conditions it is better to fail quickly; though this behavior is not guaranteed, but provided on best effort basis; never rely on this behavior for decision making in your program or for correctness of the logic.<br />
<br />
Hashtable provides both Enumerations and Iterators on certain views of the map; only Iterators throw ConcurrentModificationException for obvious reasons as stated above.<br />
<br />
HashMap/Capacity/Load/Rehashing<br />
-------------------------------<br />
Initial Capacity - can be specified in the constructor; denotes no.of buckets used for distributing the keys; specifying large initial capacity for maps that would hold large no.of items, is beneficial because auto reallocation and rehashing is avoided and hence good performance;<br />
<br />
Load Factor - can be specified in the constructor; denotes how much of current capacity has to be reached before reallocation is initiated; high load value, makes searching slow; low load value doesn't utilize the space but faster performance; trade off between time and space; default value 0.75;<br />
<br />
Rehashing - whenever capacity of the map is increased, all the keys that were distributed across buckets have to be redistributed once again across the newer no.of buckets; quite performance intensive<br />
<br />
*Values of Initial Capacity and Load Factor are just indicators; otherwise their actual behavior is implementation dependent<br />
<br />
Big O Notation or order of complexity or computation time<br />
---------------------------------------------------------<br />
Big O notation - describes a simplified maximum possible value of a function in terms of a factor variable the function depends on; this simplified function tells about what level of scale of the function value was caused by that factor variable<br />
<br />
Let n be the factor variable of a function say time taken for performing an algorithm.<br />
<br />
>Constant time O(1) - takes constant time to execute the algorithm for any n<br />
>Linear time - O(n)<br />
>Logarithmic - O(log n)<br />
>Polynomial or algebraic - O(n^c) where c > 1<br />
>Exponential - O(c^n) where c > 1<br />
<br />
Generic Types<br />
==============<br />
*arrays had always been type safe, but collections had not<br />
*a non-generic collection can hold any object or mix of different varieties(types) of objects together<br />
*things in generic syntax angle bracket are called "parameterized type" or "type parameter"<br />
*lets say the generic version of variables as 'type safe' variables<br />
*method input arguments can be declared as type safe<br />
*method return value can be declared as type safe<br />
*compiler will stop you from using any container(object) other than the one that holds the declared type (illegal attempts especially inside those, those whose signature boasts the generic type safety)<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>e.g. List<dog> getDogList(){}</dog><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>void process(ArrayList<string> nameList){}</string><br />
<br />
*generics way of allowing anything:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>List list = new ArrayList();<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>[is identical to]<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>List<object> list = new ArrayList<object>();<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>[but they are not entirely same 100%]<br />
<br />
*declarations (of all types including return args, method args) and constructors are where we put generics to convert a non-geric code into a generic code<br />
<br />
*mixing generic and non generic collections:<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>One can say, generic code is like a strict law-enforcement area, and older non-geric codes are like lawless slums; when we mix these two codes, people can break your precious laws(type safety) in the non-generic code without any complaints from the compiler, while laws are still being enforced into geric version of code; but when some objects from generic area visit non-generic area and come back home, they would have become corrupted, holding banned objects in them!<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>But then compiler does a nice thing; any possible attempt to do unsafe/unchecked operations on a generic argument in non-generic codes, generates a compiler warning; funny thing is, it generates warning regardless the attempt to modify is within the type-safety law or not.<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Generally compiler warnings do not matter; but matters when we mix generic and non-generic codes and if you heed the warning, you can detect bugs during compile time itself;<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Why at runtime still the legacy code is allowed to insert wrong type objects? because...<br />
<br />
JVM(runtime) does not know anything about generics. Generics is for compiler only. Compiler strips generics related stuff from the code through the process called "type erasure" and produces legacy version of code in class files; it even adds casting for you in the generics-stripped version.<br />
<br />
That's how arrays are different from generics. They are type safe even at runtime.<br />
<br />
They made generics feature this way to support legacy codes.<br />
<br />
Compiling with "-Xlint:unchecked" flag shows all the dangerous operations in the legacy code.<br />
<br />
So, all in all, the generics protection vanishes(even from your generics-version code) the moment you hand over your type safe collections to a legacy code or namely mixing generic and non-generic codes.<br />
<br />
Boxing/Unboxing works between primitives and wrapper objects only. They cannot convert an Object type object into wrapper objects. The wrapper objects coming out of unsafe/untyped collections are of Object type. So, Unboxing would fail there.<br />
<br />
Polymorphism and Generics<br />
-------------------------<br />
*arrays provide certain polymorphic behavior and generics collection do not<br />
*generic type should match(exactly the same with no polymorphic treatment) on left and right side of the assignment operator(=), though the variable and object involved in the assignment can be of different types with polymorphic relationship (that is the conatiners/collections are allowed to have polymorphic treatment but not to their generics type marker)<br />
<br />
*base types and generic types<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>List<jbutton> list = new ArrayList<jbutton>(); //legal</jbutton></jbutton><br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>List and ArrayList are base types; JButton is generic type;<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Object[] list = new JButton[3]; //legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>ArrayList<object> list = new ArrayList<jbutton>(); //illegal<br />
<br />
<br />
==FOLLOWING IS THE ROOTCAUSE OF ALL COMPLEXITIES IN GENERICS====<br />
public class ArrayStoreException extends RuntimeException<br />
<br />
Thrown to indicate that an attempt has been made to store the wrong type of object into<br />
an array of objects.<br />
<br />
For example, the following code generates an ArrayStoreException:<br />
<br />
Object x[] = new String[3];<br />
x[0] = new Integer(0);<br />
===========================X=============================<br />
<br />
*the above problem is due to polymorphic treatment of arrays (assigning a subtype array to a super type array reference)<br />
*since generic collections try to provide the same type safety arrays do, generic also has the possibility to encounter ArrayStoreException kind of situations; but generics does not exist at runtime and no way to handle this situation with an exception and hence this rule of 'no polymorphism facility for generic collection assignment'<br />
*type safety provided by arrays exist even at runtime<br />
*but one can put elements in a polymorphic way inside those collections; only thing is they cannot treat the collection itself in a polymorphic way<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>ArrayList<number> list = new ArrayList<number>();</number></number><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add(new Integer(0));//legal and no warnings either<br />
<br />
Method arguments<br />
----------------<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#this way you can even send Number list which contains all Integers to a method which expects Number list and might try to add Float objects to it(which is ArrayStoreException kind of situation)<br />
<br />
Wildcards<br />
---------<br />
* <!--? extends T--> allows you to pass collections that hold subtypes, to a method which expects collections holding supertype<br />
* but it takes away something that was available earlier; that is, 'it doesn't allow any unsafe operation on the type-safe collection inside that method<br />
<br />
CASE 1: no wildcard<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void process(List<animal> list)</animal><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add(new Dog()); //legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>process(new ArrayList<dog>()); //illegal</dog><br />
<br />
<br />
CASE 2: with wildcard<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void process(List<!--? extends Animal--> list)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add(new Dog()); //illegal - was legal before using wild card in generics type<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Animal ani = list.get(0);//legal - cast not required<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>process(new ArrayList<dog>()); // legal now</dog><br />
<br />
* wildcard <!--? extends T--> becomes very strict and makes all possible attempts to modify the collection or unsafe assumptions/operations on that collection as ERRORS which were earlier treated as warnings<br />
*even if T is an interface, only keyword 'extends' should be used in the wildcard syntax; e.g. <!--? extends Serializable--><br />
*'implements' keyword is not allowed in wildcard notations<br />
<br />
<br />
*wildcard <!--? super T--> allows you to do modifications also to the generic collection; this is safe because it only allows collections of T or collections of super types of T and no peers of T are allowed<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void process(List<!--? super Dog--> list)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add(new Dog());//legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add(new Cat());// compiler error<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add(new Animal());//compiler error (very strict :) super type also not allowed)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add( (Dog) (new Animal()) );//legal - but cheating and dangerous<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Animal ani = new Cat();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add((Dog)ani);//legal - but cheating and causes runtime error<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Dog d = list.get(0);//compiler error - explicit cast required<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Animal dd = list.get(0);//compiler error - explicit cast required<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>process(new ArrayList<cat>());//compiler error - no peer</cat><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>process(new ArrayList<dog>());//legal</dog><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>process(new ArrayList<animal>());//legal - super type allowed</animal><br />
<br />
#though this wildcard allows adding Dog objects, it doesn't allow adding Animal object; very funny, especially when the method accepts List marked for Animal; it also takes away the usual generics feature of castless assignment<br />
<br />
*wildcard <!--?--> indicates any collection is allowed to be passed as method argument; but disallows all possible modifications and castless assignments regarding the collection<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void process(List<!--?--> list)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add("");//compiler error<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Object obj = list.get(0);//legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Dog d = list.get(0);//compiler error<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>process(new ArrayList<dog>());//legal</dog><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>process(new ArrayList<jbutton>());//legal</jbutton><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>process(new ArrayList<animal>());//legal</animal><br />
<br />
<br />
*how <!--?--> differs from <object><br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void process(List<object> list)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add(new Integer(0));//legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>list.add("hi");//legal<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Object obj = list.get(0);//legal - obviously<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>process(new ArrayList<string>());//compiler error</string><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>process(new ArrayList<object>());//legal<br />
<br />
*how <!--?--> differs from <!--? extends Object--> [THESE TWO ARE ABSOLUTELY IDENTICAL]<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>>takes all types of collections (<integer>, <jbutton>, <object>, etc)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>>disallows all possible modifications(adding even new Object() creates compile error)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>>Object obj = list.get(0) is legal<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<br />
*how <!--?--> differs from <!--? super Object--><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>>takes only <object> collections<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>>allows adding any objects(anything at all from a Broom to Mountain) to the collection<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>>Object obj = list.get(0);//legal<br />
<br />
*wildcards can only be used for reference declarations; they cannot be used with new operators while instantiating collections because, 'new' needs absolute type to create objects in the first place;<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>List<!--?--> list = new ArrayList<!--?-->();//compile error<br />
<br />
---<br />
<br />
>generic templates only provide as placeholder in your genericfied class; attempts to use the placeholder types(like <t> or <e>, etc) in a way that would require runtime dynamic behavior change, will not compile/work because generics is a compile time feature. I have seen codes in java APIs like T t = val; t.hashCode(); since all generic types are erased at compile time and replaced with 'Object', using Object class methods on these template place holders works fine. Trying to use any other methods, other than Object class methods will cause compile error. Because this is not C++ templates!</e></t><br />
<br />
============DUE TO TYPE ERASURE=====================<br />
public class MyClass<e> {</e><br />
public static void myMethod(Object item) {<br />
if (item instanceof E) { //Compiler error<br />
...<br />
}<br />
E item2 = new E(); //Compiler error<br />
E[] iArray = new E[10]; //Compiler error<br />
E obj = (E)new Object(); //Unchecked cast warning<br />
}<br />
}<br />
==========================X===========================<br />
<br />
class Generic<k,v> {</k,v><br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void add(K k, V v){<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>k.start(); <span class="Apple-tab-span" style="white-space: pre;"> </span>//Doesn't compile because compiler can no way ensure that type K would have start() method<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
}<br />
<br />
<br />
class Generic<k extends="" thread,="" v=""> {</k><br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public void add(K k, V v){<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>k.start();<span class="Apple-tab-span" style="white-space: pre;"> </span>//COMPILES FINE<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
}<br />
<br />
Generic methods and constructors<br />
--------------------------------<br />
*type variables can only be used for a method alone<br />
*type declaration identifier is placed before the return type in the method signature<br />
*type variables have to be declared before start using them(either in the class signature or method signature)<br />
*type variables localized to a constructor is also possible; they have to placed before constructor name<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class Test{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><x> Test(List<x> list, X x){}</x></x><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public <y> void add(Y t){}</y><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
*it is possible to have a type variable same as the class name; compiler can infer what is what<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class X{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><x> X(X x){} //constructor X using generic type variable X; in this case the constructor argument is taken as generic type</x><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
* if you understand the following, you are a genious<br />
<br />
new Generic<thread, object="">().<list>hello(new ArrayList());//compiles</list></thread,><br />
new Generic<thread, object="">().hello(new ArrayList());//compiles</thread,><br />
<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//Generic class uses two generic types, and method hello() uses third generic type(localized to the method) and explicit mention of the type to a method is permitted but can be omitted; since methods can't be instantiated, this is how it looks when you say you are using a generic version of that method; if omitted, compiler can infer the type; say if hello() method only takes <thread> type objects the following will not compile since compiler's inferred type is not matching with the actual object passed</thread><br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>new Generic<thread, object="">().hello(new ArrayList());</thread,><br />
<br />
*wildcards cannot be used for defining generic classes/methods<br />
<br />
public class Test<!--? extends List-->{} //illegal - compiler error<br />
public class Test<t extends="" list="">{} //legal</t><br />
<br />
<br />
===============================================<br />
Heap Pollution<br />
<br />
Most parameterized types, such as ArrayList<number> and List<string>, are non-reifiable types. A non-reifiable type is a type that is not completely available at runtime. At compile time, non-reifiable types undergo a process called type erasure during which the compiler removes information related to type parameters and type arguments. This ensures binary compatibility with Java libraries and applications that were created before generics. Because type erasure removes information from parameterized types at compile-time, these types are non-reifiable.</string></number><br />
<br />
Heap pollution occurs when a variable of a parameterized type refers to an object that is not of that parameterized type. This situation can only occur if the program performed some operation that would give rise to an unchecked warning at compile-time. An unchecked warning is generated if, either at compile-time (within the limits of the compile-time type checking rules) or at runtime, the correctness of an operation involving a parameterized type (for example, a cast or method call) cannot be verified.<br />
<br />
Consider the following example:<br />
<br />
List l = new ArrayList<number>();</number><br />
List<string> ls = l; // unchecked warning</string><br />
l.add(0, new Integer(42)); // another unchecked warning<br />
String s = ls.get(0); // ClassCastException is thrown<br />
========================X=========================<br />
<br />
<br />
Here is something to think about:-<br />
<br />
class Hi<t> {//array type while declaring is not allowed</t><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>T[] t = null;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public <u> void hi(){ //array type like U[] is not allowed while declaring</u><br />
<u><span class="Apple-tab-span" style="white-space: pre;"> </span>Hi<u[]> h = new Hi<u[]>(); //array type is allowed while using - for a place holder type 'U'</u[]></u[]></u><br />
<u><span class="Apple-tab-span" style="white-space: pre;"> </span>Hi<string[]> hs = new Hi<string[]>(); //array type is allowed while using - for a specific type 'String'</string[]></string[]></u><br />
<u><span class="Apple-tab-span" style="white-space: pre;"> </span>Hi<integer> hi = new Hi<integer>();</integer></integer></u><br />
<u><span class="Apple-tab-span" style="white-space: pre;"> </span>}</u><br />
<u>}</u><br />
<div>
<u><br /></u></div>
<div>
<u><br /></u></div>
<div>
<u><b>Reference</b>: Kathy Sierra's SCJP Book</u></div>
<br />
</object></object></jbutton></integer></object></object></object></jbutton></object></object></object></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com1tag:blogger.com,1999:blog-5659366926389737478.post-89055959039149172532012-05-15T07:05:00.000+05:302012-07-17T23:17:45.417+05:30GIST NOTES 6 - Java Strings, IO Formatting, Parsing<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<br />
<span style="font-size: x-large;">GIST NOTES 6 - Java Strings, IO Formatting, Parsing</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
[JDK 7]<br />
<br />
String, StringBuffer, StringBuilder<br />
-----------------------------------<br />
String - immutable<br />
StringBuffer - mutable, old, synchronized(slower)<br />
StringBuilder - mutable, new, NOT synchronized(so faster)<br />
<br />
>once a String object is created, it can never be changed<br />
>String is immutable object<br />
>string contains 16bit Unicode characters<br />
>String class has zillion constructors<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>String s = "hi"; s = new String(); s = new String("abcd"); s=s.concat(" are alphabets"); and so on<br />
<br />
>though string operations make string look like mutable(modifiable), they are actually immutable; the illusion is due to silent creation of new string objects by JVM whenever someone tries/wants to modify a string<br />
<br />
>any operation on a string object does not modify that object; it merely returns appropriate result in the form of another string object<br />
<br />
>when we use string objects left and right, it looks like JVM also is creating new new String objects left and right; and many of them are lost in heap without any references to them; what happens to all those memory occupied by orphaned strings; what about the performance cost in creating so many string objects everytime? these issues were resolved by java by creating a String Literal Pool where all the string objects are cached and reused<br />
<br />
>as applications grow, string literals would occupy large part of program memory<br />
<br />
String Constant Pool/String Literal Pool<br />
----------------------------------------<br />
whenever a string is needed, JVM checks the pool first to see if a matching string is there; if yes, its reference is returned otherwise new string gets created; the strings in the pool just sit there and their references grow in count and more and more people(variables) start using the same string objects; that's why nobody is allowed to modify string objects(many people are using the same string object without being aware of each other); that's why java made String class final so that nobody changes the behavior of String objects<br />
<br />
String s = "abc"; //one object gets created and sits in literal pool; s refers to it<br />
<br />
String s = new String("abc"); //two string objects get created; object created using new operator goes to nonpool area<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//and is referred by s; whereas "abc" literal goes and sits in literal pool as an orphan (for now)<br />
<br />
>indices addressing characters in string are 0-based<br />
<br />
Common String methods<br />
---------------------<br />
charAt()<br />
*concat()<br />
equalsIgnoreCase()<br />
length()<br />
*replace(char oldchar, char newchar) - replaces all occurences of a given char with another<br />
*substring(int startIndex) - string from startIndex to end of the string<br />
*substring(int startIndex, int endIndex) - return string from startIndex to endIndex excluding endIndex char<br />
*toLowerCase()<br />
toString()<br />
*toUpperCase()<br />
*trim() - cuts leading and trailing spaces<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>*all the starred methods even if they look like, they don't modify the original string; be wary of it<br />
<br />
#arrays have member 'length', String objects have method 'length()'; be wary of compiler errors<br />
<br />
StringBuffer and StringBuilder<br />
-------------------------------<br />
>they are in java.lang package<br />
>they are used when lots of modifications to strings of characters is done; when we do many modification operation(so to speak) with string objects, we leave behind many orphaned string literals which would waste memory; hence using StringBuffer/StringBuilder leaves no such string literals behind<br />
>used when streams of characters are buffered in IO operations; blocks of data processed by StringBuilder/StringBuffer; for each block same StringBuilder/StringBuffer object can be used(efficient use of memory)<br />
>StringBuilder was added in Java 5; it is not synchronized(not thread safe) and hence faster<br />
>StringBuilder and StringBuffer are exactly the same except for thread safety and speed<br />
<br />
String s = "hi";<br />
s = s.concat(" hello"); //leaves "hi" literal behind<br />
<br />
StringBuffer s = new StringBuffer("hi");<br />
s.append(" hello"); //does not leave any other StringBuffer objects behind; there is only one object from the beginning;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//all modifications are done on the same object<br />
<br />
>since StringBuffer methods return the resulting StringBuffer objects just like String class methods (but unlike String it modifies itself first), operation chaining can be done as follows:-<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>s.append(" how are you?").reverse().insert(3, "dude "); //all operations are done over and over the same object finally resulting<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//in some bizzare output :)<br />
<br />
>hmmm, I wonder what happens to those string literals we use as input arguments to StringBuffer constructors and methods; they still stick around?<br />
<br />
>StringBuffer - it's called buffer because it is synchronized, threadsafe and like an actual buffer<br />
<br />
>StringBuilder - it's called builder, because its only purpose is to allow people build and play with strings of characters (no thread safety)<br />
<br />
>StringBuffer.append() can take boolean, byte, char, double, float, int, long and others as well<br />
<br />
>StringBuilder.delete(int startIndex, int endIndex) - deletes chars from startIndex to endIndex excluding endIndex char from the orignal object and returns the reference it itself<br />
<br />
>StringBuilder.insert(int indexToPlace, String stringToPlace) - stringToPlace is inserted at index indexToPlace; in the final string the first char of stringToPlace will be at index indexToPlace.<br />
<br />
>StringBuffer.reverse() - characters are reversed; last char comes to first; and so on<br />
<br />
File Navigation and IO<br />
======================<br />
<br />
File -> object pointing to a file or director; create new file, delete files, search files, make new directories are done by this class<br />
<br />
FileReader -> reads character files; low-level character reading methods; every read operation is performance intensive<br />
<br />
BufferedReader -> makes low level reader classes more efficient and user friendly; reads relatively large chunks at once and buffers, hence high performance; minimizes no.of times the time-intensive file read operations is performed; works with buffer; can read lines instead of character<br />
<br />
FileWriter -> char based low level writer; every write operation is performance intensive/time consuming<br />
<br />
BufferedWriter -> wraps low level wrtiers(e.g. FileWriter); less no.of writes; works with buffer to save time and effort; writes larger chunk at once; can write a line at a time;<br />
<br />
PrintWriter -> enhanced in java 5; this can use a string or a file as the data source ; flexible and powerful methods<br />
<br />
Console -> new in Java 6; reads input from console; writes formatted output to the console;<br />
<br />
Stream classes -> read/write bytes (associated with serialization also)<br />
Readers and Writers -> read/write characters<br />
Buffered Reader/Writer -> read/write lines(usually)<br />
<br />
File class objects represent files or directories, not the data inside the file.<br />
<br />
File<br />
-----<br />
>Instantiating a new File object doesn't create a file on the disk<br />
>Instantiating FileWriter object automatically creates the mentioned file on the disk if it doesn't exist already<br />
>FileWriter.flush() method call is necessary to make sure that every last bit of data we wrote was sent to the file; since a kind of buffering is done in the write stream, one has to make sure the every last bit was written to the file; hence you call flush() when you are done writing<br />
>flush() is not available in Reader classes; no flushing is required while reading<br />
>FileReader/FileWriter.close() method releases all operating system resources related to the file; once your job is over, no need to hang on to those precious OS resources; so we call close()<br />
<br />
>FileReader.read(char[]) will read the entire file into the array or as much as the size of the array and return the count of chars read accordingly<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>File myDir = new File("mydir");<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>myDir.mkdir();//create directory<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>File file = new File(myDir, "log.txt");<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>file.createNewFile(); //create a file under that directory<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>file.renameTo(new File("log_renamed.txt")); //rename a file<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>file.delete(); //delete a file<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>myDir.renameTo(new File("mydir_renamed")); //rename a directory<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>String[] contents = myDir.list(); //returns an array of files and directories in myDir<br />
<br />
>PrintWriter(File) can directly write into a file - we don't need FileWriter<br />
>non-empty directory cannot be deleted<br />
<br />
>System.console() returns reference to java.io.Console object; if the runtime environment(machine) has no console device (application not run from command line), then it returns null<br />
<br />
Console<br />
-------<br />
>can accept input both echoed and nonechoed(passwords)<br />
>can print formatted output to the console<br />
>Console.readLine() returns String (input from console)<br />
>Console.readPassword() returns the user input as char array; because arrays can be destroyed easily after use(GC collected), but String literal would be lying around in the literal pool which a notorious hacker might get hold of.<br />
<br />
Serialization<br />
-------------<br />
>serialization/deserialization can use java.io: DataInputStream,DataOutputStream,FileInputStream,FileOutputStream,ObjectInputStream, ObjectOutputStream, Serializable<br />
<br />
>Serialization involves objects - hence Object input/output stream<br />
>Serialization involves persisting objects into files - hence File Input/Output Stream<br />
>Serialization involves transferring objects over the network - hence Data Input/Output Stream<br />
>Serialization involves binary data - hence it is Stream based classes (not Writer/Reader or Buffered based classes)<br />
>Serialization involves writing binary output for converting objects to bits(serialization) - hence Output classes<br />
>Serialization involves reading binary input for converting bits to objects(deserialization) - hence Input classes<br />
<br />
[enough? :)]<br />
<br />
Serialization - saving object and its state (all member data except transient variables - it's a feature)<br />
<br />
>Mark unwanted variables as transient if you don't want them to be saved/persisted<br />
<br />
Serialize: ObjectOutputStream.writeObject(Object obj)<br />
Deserialize: ObjectInputStream.readObject() - returns Object<br />
<br />
ObjectOutputStream and ObjectInputStream are considered higher level classes in java.io package because they deal with the cool Objects. Since, they are higher level you can wrap them around lower level classes like FileInputStream and FileOutputStream.<br />
<br />
>FileOutputStream(String filename) constructor automatically creates the file if it doesn't exist<br />
>wrap FileOutputStream object into ObjectOutputStream object and start serializing objects with writeObject method<br />
>writeObject() - serializes and writes into the stream (can be a file stream or network stream)<br />
>readObject() - reads from stream and deserializes object; that is reconstructs the objects and gives it to you<br />
<br />
>when you serialize an object, java serializes the entire "object graph"; that is all the objects inside your object and further down and so on; "a deep copy" of everything the saved object needs to be restored<br />
<br />
>all the objects inside your object should be serializable; otherwise exception is thrown at runtime<br />
<br />
>you can choose to ignore unserializable object members in your class by marking them as 'transient'<br />
<br />
>sometimes the member object may be of a third party class whose source code you don't have; in such cases, it is hard to make that member as serializable; so you can mark that member as transient and get on with your serializing business; but when you restore your saved object it will not have this third party object member properly initialized; if you can't live without this third party object, there is a way to intervene serialization/deserialization processes in the middle and save/read some extra data obtained from the third party object, so that you will be able to restore that object too.<br />
<br />
Serialization mechanism provides the following sneaky way to help you add extra bits to your serialized data. Provide the following pair of private methods(with exact signature as given) in your class which you are attempting to serialize but which contains an unserializable third party object:-<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>private void writeObject(ObjectOutputStream os) {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>os.defaultWriteObject(); //ask JVM to do the usual serialization<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>os.writeInt(thirdPartyObject.getData()); //add third party data bits manually to serialization stream<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>private void readObject(ObjectInputStream is) {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>is.defaultReadObject(); //ask JVM to do the usual deserialization; this restores your parent object back<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>thirdPartyObject = new ThirdPartyObject();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>thirdPartyObject.setData(is.readInt()); //read back the extra bits u added during serialization, and restore your third party<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//object manually<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
#reading the extra data is done in the same order as it was done during writing time<br />
<br />
#these two methods look similar to ObjectOutputStream/ObjectInputStream class methods; but these are different; only the names are same; the input argument is different and these are 'private' methods!<br />
<br />
#how the hell JVM manages to call our private methods? why serialization mechanism provides such 'informal' way to do some manual serialization?<br />
<br />
#this methodology is used when you have to save some part of the obejct state manually<br />
<br />
#why not all classes in java are serializable? why didn't they make Object class serializable?<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>One thing is for security reasons. Not all objects are safe to be left around in files or sent over network. And those classes which are runtime specific obviously makes no sense to serialize and save them; e.g. streams, threads, runtime, some GUI classes connected to underlying OS, etc.<br />
<br />
Inheritance affects Serialization<br />
---------------------------------<br />
<br />
>If parent class implements Serializable, all sub classes automatically become serializable; but any new non-serializable member introduced in subclasses will cause runtime error<br />
<br />
>so to check whether a class is serializable or not, one has to examine the entire class hierarchy not just that class alone<br />
<br />
>Object class does not implement Serializable<br />
<br />
>when an object is constructed using new operator, the following things happen in that order<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>1.All instance variables are assigned default values (even if some of them have initial value in their declaration they are not used yet)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>2.The constructor is is invoked which invokes super class constructor(or other constructor of the same class and then superclass constructor ultimately)<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>3.All superclass constructors complete<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>4.Instance variables that are assigned initial values as part of their declaration are given those values<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>5.The constructor complete<br />
<br />
#All the above things DO NOT HAPPEN when an object is deserialized(when all ancestors are also serializable)<br />
<br />
>Deserialization does not call the constructors (or super class constructors for that matter)<br />
>Deserialization does not provide initially assigned values(as part of the declaration) to data members<br />
>Otherwise, it would defeat the purpose of restoring the object state right? we don't want initial values of a brand new object; we want what we saved<br />
>transient variables also do not get their declared initial values; instead they get default values after restoration (if private void writeObject() is not implemented sneakily)<br />
<br />
Subclass is Serializable Super class is NOT<br />
-------------------------------------------<br />
>So, coming to inheritance, if a class implements Serializable and its super class is not serializable, the above said rule of skipping the normal object initialization routines (constructors, member initialization) is BROKEN partly<br />
<br />
>object initialization process is done starting from the first non-serializable parent all the upto top most parent in the class hierarchy<br />
<br />
>that is, any member as part of non-serializable super class does not get restored when we deserialize the child; those inherited member variables get brand new values as though we are creating a new object using 'new' operator (remember it's only for parent members)<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class Animal {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>int weight = 10;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class Dog extends Animal implements Serializable {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>String name;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Dog(int w, String n)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>weight = w;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>name = n;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
#in this example, if you persist a dog with weight = 20 and name = Sally, and restore it back, you will see that weight became 10(not good) and name is Sally(as expected).<br />
<br />
>So, when you try to serialize your class, be wary of those inherited members of a non-serializable super class; they will not participate in your serialization process no matter what; you should do something else if you want to persit them too<br />
<br />
>when serializing an array or collection, all elements should be serializable; otherwise, runtime error<br />
<br />
Static variables not serialized<br />
-------------------------------<br />
>Serialization only applies to objects; though static variable values can change and needs to be preserved, they are still not part of any object; they are part of the class itself; so they are never bothered about in serialization and deserialization<br />
<br />
Versioning issue in serilization<br />
--------------------------------<br />
>when you save an object using one version of the class, and attempt to restore it with another version of the same class, then serialization will fail<br />
>if you open the serialized file, you could still make out the values of private fields of the stored object; if you attempt mess up with the serialized file, it throws StreamCorruptedException when you restore the object from that modified file<br />
<br />
Object Serialization System Specification<br />
=========================================<br />
<br />
>Objects to be saved in the stream may support either the Serializable or Externalizable interface<br />
>For serializable objects, the stream includes sufficient information to restore the fields in the stream to a compatible version of the class<br />
>For Externalizable objects, the class is solely responsible for the external format of it contents<br />
>when an object is stored, all other objects reachable from this object are stored as well to maintain the relationship between the objects<br />
>objects are written with writeObject() method from ObjectOutput and primitives are written to the stream with the methods of DataOutput<br />
<br />
========[WE WILL CONTINUE SERIOUS SERIALIZATION in other post]========<br />
<br />
<br />
<br />
Dates, Numbers and Currency<br />
---------------------------<br />
<br />
java.util.Date - most of the methods are deprecated; the instance of this class represents a mutable date,time to a millisecond; this object can act as a bridge between Calendar and DateFormat classes<br />
<br />
java.util.Calendar - allows manipulation of dates and time; this is an abstract class; use getInstance() overloaded static factory method to get hold of a Calendar object<br />
<br />
java.text.DateFormat - it provides many styles of date formatting and also in many Locales<br />
<br />
java.text.NumberFormat - formatting numbers and currencies in locales around the world<br />
<br />
java.util.Locale - Every Locale around the world, has different time, currency, and formatting styles for date, numbers and currency; to cater to this need, Local class can work with DateFormat, NumberFormat and Calendar classes<br />
<br />
new Date() - points to current time<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
Calendar c = Calendar.getInstance() - c allows you to perform date time manipulations in your locale<br />
<br />
Locale loc = new Locale(language) or new Locale(language, country) - gives you locale objects<br />
Calendar c = Calendar.getInstance(loc) - gives you the calendar for a specific locale<br />
<br />
A DateFormat object can be created for a particular style and Locale.<br />
<br />
A NumberFormat object can be created for a particular Locale.<br />
<br />
Since, Date class did not handle the Internationalization and Localization situations well, most of its methods were deprecated, and Calendar could be used instead.<br />
<br />
Date.setTime() and getTime() methods are still usable and work with long values (time in milliseconds)<br />
<br />
Calendar c = new Calendar(); //Illegal code<br />
<br />
Calendar c = Calendar.getInstance();//legal, returns one of the concrete subclasses of Calendar class(could be java.util.GregorianCalendar)<br />
<br />
Calendar.setTime(Date d) - sets the calendar time to any arbitrary date you pass<br />
<br />
In some locales, first day of the week is 'Monday'. To find this out use, calendar.getFirstDayOfWeek() [returns a predefined Calendar constant, e.g. Calendar.SUNDAY].<br />
<br />
calendar.add(Calendar.HOUR, -4); //subtracts 4hrs from calendar object time<br />
calendar.add(Calendar.YEAR, 2); //adds 2yrs to the time<br />
calendar.add(Calendar.DAY_OF_WEEK, -2); //subtracts 2 days from calendar's time<br />
<br />
calendar.roll(Calendar.MONTH, 10); //adds 10 units to the specified time unit and lets it overflow; in this example, it only changes month<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//the year of the calendar's time remains as it is; while adding 10 to the current month, it it goes<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//beyond 12, then 12 is subtracted and the remaining number is treated as the resulting month; so it<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//can either increase or decrease any time unit(hour, day, month or year)<br />
<br />
> roll() doesn't change the larger part of the date than the part specified in the input argument.<br />
<br />
DateFormat<br />
----------<br />
DateFormat.getDateInstance(DateFormat.FULL, new Locale("it","IT")) will create italian dateformat object. Locale can be set to DateFormat only at the time of instance creation. After that no way to change the locale on the existing DateFormat object. Applies to NumberFormat objects also.<br />
<br />
Locale indiaLocale = new Locale("hi","IN");<br />
indiaLocale.getDisplayCountry() - gives a string name of the country(INDIA) in the default locale(can be any locale)<br />
indiaLocale.getDisplayCountry(new Locale("it","IT")) - gives INDIA in italian locale<br />
indiaLocale.getDisplayLanguage() - gives string name of the language(HINDI) in the default locale<br />
indiaLocale.getDisplayLanguage(new Locale("it","IT")) - gives HINDI in italian locale<br />
<br />
API<br />
---<br />
new Date();<br />
new Date(long millis);<br />
<br />
Calendar.getInstance();<br />
Calendar.getInstance(Locale l);<br />
<br />
Locale.getDefault();<br />
new Locale(String language);<br />
new Locale(String language, String country);<br />
<br />
DateFormat.getInstance();<br />
DateFormat.getDateInstance();<br />
DateFormat.getDateInstance(style);<br />
DateFormat.getDateInstnace(style, Locale);<br />
<br />
NumberFormat.getInstance();<br />
NumberFormat.getInstance(Locale);<br />
NumberFormat.getNumberInstance();<br />
NumberFormat.getNumberInstance(Locale);<br />
NumberFormat.getCurrencyInstance();<br />
NumberFormat.getCurrencyInstance(Locale);<br />
<br />
Parsing, Tokenizing and Formatting<br />
==================================<br />
<br />
>In general, a regex search is run from left to right, and once a source's character has been used in a match(consumed), it cannot be reused.<br />
<br />
\d digits<br />
\s white space<br />
\w word characters(alphabets, digits and underscore)<br />
[a-zA-Z] range of characters<br />
^ negate characters specified<br />
[][] nested brackets - union of sets<br />
&& intersection of sets<br />
. any single character<br />
<br />
Qauntifiers:<br />
-----------<br />
+ one or more<br />
* zero of more<br />
? zero or one<br />
<br />
<br />
Match hexadecimal numbers --> 0[xX]([0-9a-fA-F])+<br />
<br />
Match anything that is not a or b or c --> [^abc]<br />
<br />
Match 7 digit phone number which may or may not contain a space or a hyphen after the 3rd digit --> \d\d\d([-\s])?\d\d\d\d<br />
<br />
? greedy (zero or one)<br />
?? reluctant (zero or one)<br />
* greedy (zero or more)<br />
*? reluctant (zero or more)<br />
+ greedy (one or more)<br />
+? reluctant (one or more)<br />
<br />
Greedy quantifier, to consume as much as possible, it reads the entire source, and then starts matching from right to left so that it can consume as much as possible from the left hand side when a match is found.<br />
<br />
\ backslash is a meta character and hence has to be escaped in java source file.<br />
<br />
patternexpression = "\d"; //will not compile<br />
patternexpression = "\\d"; //will compile<br />
<br />
patternexpression = "\\."; //search for a dot; dot is not the regex meta char here because it is escaped with slash<br />
<br />
>delimiters in tokenizing can be as big a string as represented by a complex regex<br />
<br />
String.split(String regex) - tokenizes the entire string<br />
Scanner - can do on the fly tokenizing and you can quit tokenizing if you have found your token already (need not tokenize the whole file)<br />
<br />
Scanner<br />
--------<br />
>Scanner's can be constructed using files, streams or strings as a source.<br />
>Tokenizing is performed in a loop; so you can exit the loop at any time<br />
>Tokens can be converted to their appropriate primitive types automatically<br />
>Scanner's default delimiter is white space<br />
<br />
Scanner.useDelimiter() lets you set the delimiter to be any regex.<br />
<br />
Scanner s = new Scanner("source string which has to be tokenized");<br />
<br />
s.next() returns next token as a String; e.g. "source" in this example<br />
<br />
java.io.PrintStream<br />
-------------------<br />
>format() and printf() are exactly equal to each other<br />
<br />
>format() method uses java.util.Formatter class behind the scenes<br />
<br />
Format string syntax:<br />
<br />
%[arg_index$][flags][width][.precision]conversion_char<br />
<br />
values within [] are optional; just the percentage and conversion_char are enough.<br />
<br />
e.g. System.out.printf("%2$d + %1$d",123,456); //prints '456 + 123'<br />
<br />
arg_index --> an integer followed by $; indicates which argument should be printed in this position<br />
<br />
flags --><br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- left justify<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>+ include sign(+ or -) with this argument<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>0 pad this argument with zeros<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>, use locale specific grouping separators<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>( enclose negative numbers in parenthesis<br />
<br />
width --> indicates minimum no.of characters to print; used for column formatting<br />
<br />
precision --> to format floating point numbers; indicates no.of digits to print after the decimal point<br />
<br />
conversion_type --><br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>%b boolean<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>%c char<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>%d integer<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>%f floating point<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>%s string<br />
<br />
System.out.format("%d", 12.3); //throws IllegalFormatConversionException<br />
<br />
System.out.printf("%1$+-7d", 46); //first argument is used, includes sign, left justifies, 7 width space is used, integer is expected<br />
<br />
# StringBuffer/StringBuilder.equals() is not overridden; it doesn't compare values<br />
<br />
# The String.split() method tokenizes the entire source data all at once, so<br />
large amounts of data can be quite slow to process.<br />
<br />
#PrintWriter - is a writer/helper class which uses other streams to write<br />
#PrintStream - is a stream itself extending from FilterOutputStream class<br />
#System.out and System.err are PrintStream objects<br />
#PrintWriter uses PrintStream and Formatter internally; generally it uses OutputStreamWriter unless the user passes his own output stream for file writing<br />
<br />
<b>Reference</b>: Kathy Sierra's SCJP Book</div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-66197456941557342652012-05-10T07:01:00.000+05:302012-07-17T23:17:45.351+05:30GIST NOTES 5 - Java Flow Control, Exceptions & Assertions<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<span style="font-size: x-large;">GIST NOTES 5 - Java Flow Control, Exceptions & Assertions</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
[JDK 7]<br />
<br />
>Exceptions and Assertions are new flavors of flow controls specific to java language<br />
>conditionals: if and switch<br />
>looping constructs: for, while, do<br />
>Exceptions: way to organize code that deals with problems that might crop up at runtime<br />
>Assertions: (from 1.4 onwards) way to do testing and debugging checks on conditions that are apparent at development time; helps to avoid runtime overhead associated with exception handling<br />
<br />
if and switch<br />
-------------<br />
>these two are referred to as "decision statements"<br />
>if takes only expressions that evaluate to a boolean value true or false<br />
>one can have zero or one "else" for a given "if" and it must come after all "else ifs"<br />
>zero or more "else ifs" are permitted but should come before "else" if "else" is there at all<br />
>once an "else if" succeeds none of the remaining "else ifs" or "else" will be tested<br />
>when 'if's are nested, and when in confusion regarding which 'if' the 'else' is paired to, go for the closest preceding 'if' that doesn't have 'else'<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if(check)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if(check1)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>statement;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>else<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>statement1; //this else belongs to check1 if<br />
<br />
> in (x && y | z) expression, (y|z) is evaluated first(really?) and with the result && is performed(really??)<br />
sadly if(($+="c")!="" && ($+="b")!="" | ($+="a")!="")<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("condition passed, $="+$);<br />
prints:: condition passed, $=cba<br />
<br />
> if(0) is illegal in java; only boolean is allowed in conditionals<br />
<br />
>switch: a way to simulate the use of multiple if statements<br />
>general form of switch-case<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>swtich (expression) {<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>case constant1: code block<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>case constant2: code block<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>default:<span class="Apple-tab-span" style="white-space: pre;"> </span>code block<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
>switch's expression must evaluate to char, byte, short, int or enum; except for enum all others can be automatically promoted to int<br />
>so, essentially switch expression is only friendly to int and enums<br />
>long, float and double values are not allowed(compile error)<br />
>case constants must evaluate to the same type as the switch expression can use<br />
>case constant MUST be a compile time constant or a final variable that was initialized in declaration statement itself<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>final int a = 1;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>final int b;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>b = 2;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>int x = 3;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>switch(x){<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>case a: //OK<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>case b: //Compile Error<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
>switch can only check for equality with case constants; other relational operators are unusable in a case<br />
>when case constant is too large for the data type of the expression used in switch, compilation fails<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>byte b = 2;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>switch(b){<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>case 128:<span class="Apple-tab-span" style="white-space: pre;"> </span>//compile error<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
>two cases with same constant doesn't compile<br />
>simple expression is allowed in place of case constant; but it must resolve at compile time<br />
>autoboxing can be used in switch expression; but cannot be used in case constant<br />
>no wrapper objects are allowed for case constant(compile error)<br />
>default block is optional in switch<br />
<br />
Break and Fall-through in switch<br />
--------------------------------<br />
<br />
>execution goes from top to bottom<br />
>execution entry point starts at the first case that matches<br />
>all the cases(including default) that follow the first matched case also will be executed; it is up to us to break away<br />
>once a break statement is found, control exits the switch block<br />
>the execution falls through all the cases starting from entry point case<br />
>default option is just like any other case and it can also come in any place not necessarily at the last; fall-through also happens through default option<br />
<br />
while loop<br />
----------<br />
>variables used in while condition should be declared prior to while loop<br />
>while(int x = 0) {} is ILLEGAL<br />
>while loop may not run ever at all if the condition fails at the first attempt itself<br />
>expression should resolve to boolean<br />
<br />
do-while loop<br />
-------------<br />
>first executes and then only checks for condition to continue<br />
>guaranteed to run at least once<br />
>semicolon is needed at the end of the loop<br />
>expression should resolve to boolean<br />
<br />
for loops<br />
----------<br />
>basic for loop: older version of for loop<br />
>for-in/for-each/enhanced-for: newer version (from 6.0 onwards)<br />
<br />
for(statement1 ; bool_expression; statement2)<br />
{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//loop body<br />
}<br />
<br />
bool_expression - should evaluate to boolean value<br />
<br />
statement1 - should be an assignment statement or variable declaration (some kind of variable assignment is expected here); or variable declaration even without initialization is fine; multiple variables of the same type also allowed here, but they should be comma separated<br />
<br />
statement2 - should be an assignment statement usually; no variable declaration is allowed here; multiple assignment statements separated by comma are allowed as well; any other java statement is also allowed here<br />
<br />
Both statement1 and statement2 cannot be mathematical expressions evaluating to a value or an object<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>for(Thread t; b<c; b="c) </p"></c;><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//LEGAL for loop provided b and c are valid variables<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>for(Thread t = null, t2 = null, t3 = new Thread(); 1 < 2; b = c, c = b, b = c)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//LEGAL for loop; b and c can be any objects as well<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
Execution:<br />
<br />
1. statement1: runs only once at the beginning of the for loop initially<br />
2. bool_expression and statement2 are run on every iteration of the for loop<br />
3. scope of the for loop variable ends with for loop; it is not visible outside of the for loop<br />
4. command separated boolean expressions in bool_expressions is NOT permitted<br />
5. statement2 runs from 2nd iteration only; it is not touched on first iteration of the for loop<br />
6. on first iteration statement1 and bool_expression are executed; then loop body is executed<br />
7. on a normal exit from a for loop, evaluation of statement2 and then the evaluation of bool_expression are the last operations done before exiting the for loop (exception: forced exit using break/return/System.exit() statement)<br />
<br />
>statement1, bool_expression and statement2 are all optional; and they are all independent<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>for(;;)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//LEGAL for loop which runs infinitely<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>for(Thread t = null, t2 = null, t3 = new Thread(); 1 < 2; b = c, c = b, b = c, System.out.print("Hello"),lp.hi(),new Object())<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//LEGAL for loop; any arbitrary code with comma separation can go in statement2<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<br />
Enhanced for loop<br />
------------------<br />
<br />
>can be used to iterate through an array or collection<br />
>for(declaration : expression) is the general format<br />
>declaration should be of type compatible with the array/collection returned in expression part; this variable receives the element of the array on each iteraion<br />
>'expression' can be a direct array/collection or a method call that returns array/collection which is compatible with the 'declaration' part<br />
>array can be of primitive, objects or array of arrays type<br />
<br />
Break and continue<br />
------------------<br />
break - stops the entire loop; should be placed inside a loop (except for labeled break statements)<br />
continue - stops just the current iteration; should be placed inside a loop; otherwise compile error<br />
<br />
>when continue ends the current iteration; still the "iteration expression" (stnatement2 in our case) runs; continue just tells to finish up the current iteration prematurely, that is all; nothing else changes<br />
<br />
>both break and continue do not change in behavior in case of nested loops; they only act on the inner most loop (except for labeled break)<br />
<br />
>continue can be used inside if loop(which is inside a for loop); but it still acts only on for/while/do loops; 'if' is not considered a loop for break or continue<br />
<br />
>both continue and break can be unlabeled or labeled<br />
<br />
Labeled Statements<br />
------------------<br />
>Labeled varieties are required only when there are nested loops.<br />
>Instead of operating on the innermost loop, they operate on the loop whose lebel is specified<br />
>a label(ending with colon) is placed just before the loop<br />
>label names should be valid variable names<br />
<br />
e.g.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>outer:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>for(;;)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>while(true)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if(true)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>break outer; //comes out of for loop instead of while loop<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
//"continue outer;" skips the current iteration and goes to the next iteration of the 'for' loop<br />
<br />
>> the break and continue statements should be inside the labeled loop; using arbitrary loop names(labels) invites compile error<br />
<br />
Exception Handling<br />
==================<br />
<br />
>The term "Exception" means "exceptional condition" that alters the normal program flow<br />
>hardware failure, resource exhaustion, coding bugs can cause exceptions<br />
>when this exceptional event occurs in java, an exception is said to be "thrown"<br />
>the code that is responsible for doing something about the exception is called "exception handler", and it "catches" the thrown exception<br />
>exception handling is nothing but transferring the execution of the program to an appropriate exception handler when the exception occurs<br />
>we need a way to tell the JVM what code to execute when exception occurs; that is where try-catch block comes to use<br />
>try block holds the code that may throw exceptions; this region is called "guarded region", that is risky code goes inside try block<br />
>followed by try, one or more catch blocks are provided each block matching a specific exception or a group of exceptions; each catch block has appropriate exception handling code<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>try{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//dangerous code goes here<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>} catch(ExceptionOne e) {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//handle exception 1<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>} catch(ExceptionTwo e) {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//handle exception 2<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
> all catch blocks should immediately follow try block; no code is allowed in-between these blocks;<br />
> order of the catch blocks is crucial<br />
> when an exception occurs in try block at a particular line, the control immediately jumps to one of the catch blocks; remaining code lines in try block are skipped<br />
> after executing one of the matching catch blocks the control comes out of the entire try-catch block; that is only one catch block executes and other catch blocks are skipped<br />
<br />
finally block<br />
-------------<br />
>when an exception happens, you might want to do some cleanup; you can't put clean up code in try because some code lines are skipped when exception occurs; if you put it in catch block, then you have to duplicate the clean up code in all catch blocks; so we are saved with finally block to do just that<br />
>finally block executes always regardless of whether exception occurs or not<br />
>even if there is a return statement in try block, finally block still executes right after the control encounters the return statement and before return executes<br />
>so finally block is the ideal place to close files, release sockets, db connections and other cleanup codes<br />
>finally block executes right after try or catch executes depending upon whether exception happened or not<br />
>finally always runs<br />
>if exception is not caught by any catch blocks, still finally runs<br />
>finally block is optional (code will compile without finally)<br />
>catch block also can be omitted if there is try and finally blocks (just the 'try' block will not compile)<br />
>try with only finally is used sometimes to pass the exception back to the calling method<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>try{ //pass the exception back to the caller<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//do stuff<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>} finally {<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//clean up<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
>catch block is not allowed after finally block<br />
<br />
>propagating uncaught exception - not all exceptions need to be caught; try without any catch block helps to duck(pass the buck) the exceptions; to let the calling method handle for us; so here the exception is propagated to the previous method in the call stack; the exception may be further passed/ducked by subsequent methods in the call stack till someone is willing to handle it; if no method ever handles that exception even main method, then JVM finally handles it and terminates with a crash<br />
<br />
Defining Exceptions<br />
-------------------<br />
>all exceptions in java are objects whose super class is java.lang.Exception<br />
>throwing exception means, some object of subtype of Exception is created and handed down to you<br />
>who create these Exception objects? well, anyone can create one. You can create. Java standard libraries create. The APIs you use would create. JVM creates.<br />
<br />
Exception Class Hierarchy<br />
-------------------------<br />
<br />
Throwable derives (extends) from Object class.<br />
Error and Exception classes derive from Throwable.<br />
RuntimeException derives from Exception.<br />
If you want to define your own exception, you should derive it from Exception class.<br />
<br />
>class Error is thrown when unusual situations occur that are not caused by program errors; e.g. JVM running out of memory; generally application won't be able to recover from these Errors and hence you are not required to handle errors;<br />
>Errors are not Exceptions because Error does not derive from Exception class; not handling Error will not cause compilation failure<br />
<br />
>Exception generally indicates resources not availble, communication failure and such genuine conditions, not just bugs<br />
>RuntimeException deriving from Exception do sometimes indicate bugs in the program or program errors; they also indicate rare difficult to handle exceptional conditions<br />
<br />
>printStackTrace() method from Throwable class provides a description about the Error or Exception; this method prints all the methods from where the exception started all the way through the stack till the point where it is being caught; if not caught, it prints till main method<br />
<br />
>Throwable class indicates that its objects can be used with keywords 'throw', 'throws', 'catch'<br />
<br />
>IndexOutOfBoundsException has two subclasses: ArrayIndexOutOfBoundsException and StringIndexOutOfBoundsException; by catching the superclass exception you can handle both subclass exceptions (handling entire class hierarchy of exceptions)<br />
<br />
>catching too many types of exceptions in one 'catch' defeats the design objective; might reduce the reliability of the program because it may not know how to handle certain exceptions caught by it<br />
<br />
>more specific exceptions should be caught first and then generic exceptions should be caught; if any catch block tries to catch a specific exception which is already caught by a generic catch block, it causes compile error; trying to catch same exception in two catch blocks causes compile error;<br />
<br />
>FileNotFoundException is a subclass of IOException<br />
<br />
>unrelated exceptions(no polymorphic relationship) can be caught in any order<br />
<br />
>any method that can cause an exception should either handle the exception or declare that in method signature using 'throws' clause; if the exception in question is of type RuntimeException, then no need to handle or declare; unhandled and undeclared RuntimeExceptions will not cause compile error but will terminate the program (if not handled all the way up to main) in the middle of the execution<br />
<br />
>all interfaces and classes should declare the exceptions in their method declarations<br />
<br />
>if you call another method that throws an exception from your method, either you can handle it, or tell the world an exception might come from your method by declaring it in your method; this is exception propagation<br />
<br />
>even methods that are "ducking" the exceptions should declare those exceptions in their signature<br />
<br />
>any exception that is not a subtype of RuntimeException is called 'Checked Exception'; all checked exceptions should have been caught and handled or declared to be thrown during compile time; (called 'handle or declare requirement')<br />
<br />
>no need to declare RuntimeException; even if you declare, compiler will not complain; also compiler will not make sure the users of your code handle this exception; nobody(compiler, your API users) cares whether you handle RuntimeException or not; but for your program to function properly you have to handle it somewhere of course;<br />
<br />
>RuntimeException, Error and all of their subtypes are unchecked exceptions; unchecked exceptions do not have to be specified or handled<br />
<br />
>examples for unchecked exceptions: NullPointerException, ArrayIndexOutOfBoundsException, OutOfMemoryError<br />
<br />
>checked exceptions are called 'checked' because compiler checks to see if all possible such exceptions are handled in one place or the other; these are the exceptions that are evident in the code structure itself<br />
<br />
>you can throw existing java API exceptions or your own exception class<br />
<br />
>even main() method can pass the buck by declaring exceptions originating from it<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class A {<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>public static void main(String[] args) throws Exception //LEGAL<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>throw new Exception();<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<br />
>Error is not an Exception; but still both of them are throwable; no need to catch or handle Errors; but you can; you can throw an Error object also; usually when error occurs it is impossible to rectify and continue the program - usually JVM exits on Errors.<br />
<br />
>neither the compiler, nor the JVM, or me, or the designer, or your manager or anyone else for that matter, expect you to handle Errors (like OutOfMemoryError) in your code<br />
<br />
>and I don't know why in the world you would want to throw Errors like OutOfMemoryError yourself in your code<br />
<br />
>not only you can throw a new exception, you can also rethrow an exception you just caught in your catch block; that rethrown exception will not be handled by any other peer catch blocks in the same try; after running finally, the rethrown exception is pushed to next method in the call stack<br />
<br />
>suppose if you rethrow a checked exception, you have to either handle it or declare it in your method signature; rethrown exception is treated as a fresh one.<br />
<br />
Common Exceptions/Errors<br />
-------------------------<br />
<br />
JVM thrown exceptions:: errors or exceptions thrown by JVM<br />
<br />
NullPointerException: is thrown by JVM while attempting to use a null reference to access members<br />
<br />
StackOverflowError: when infinite recursive method calls happen, RAM memory runs out due to growing stack memory and this error is thrown by JVM<br />
<br />
Programmatically Thrown Exceptions:: exceptions explicitly thrown by application or API programmers<br />
<br />
NumberFormatException: thrown by API when parsed number is malformed<br />
<br />
AssertionError: though it is not an exception, it is thrown programmatically<br />
<br />
Your own homemade exceptions also fall into the category of programmatically thrown exceptions.<br />
<br />
JVM Thrown<br />
-----------<br />
>ArrayOutOfBoundsException<br />
>ClassCastException<br />
>NullPointerException<br />
>ExceptionInInitializerError - from static block<br />
>StackOverflowError<br />
>NoClassDefFoundError - jvm can't find the class file (command line error or classpath issue)<br />
<br />
Programmatically Thrown<br />
-----------------------<br />
>IllegalArgumentException - a method receiving bad input argument<br />
>IllegalStateException - state of the environment doesn't match; e.g. trying to use already closed Scanner <br />
>NumberFormatException<br />
>AssertionError<br />
<br />
Assertion Mechanism(from java 1.4)<br />
==================================<br />
<br />
Assertions let you test your assumptions during development, without the expense of writing exception handlers for exceptions that you assume will never happen once the program is out of development and fully deployed.<br />
<br />
>so assertion is not a replacement to exception mechanism?<br />
<br />
>It's like this: Say you have a bunch of assumptions about your application during the development time (you are in the phase of figuring out your own application design as you develop one might say); you want to validate whether your assumptions are right or wrong; so you have to put some checks in your program at appropriate points; after you are done with cross checking, you no longer need those check points as part of your application; so you go ahead and remove those check points; well, imagine the effort gone into putting those check points in the first place and then removing them; those check points could be try-catch blocks, if-else blocks; print statements; formal exception handling mechanism is a way costlier to your development time as well as if you leave them around, it might be a performance hit to your application in the deployment; so what do we do? use assertions as check points; when you ship your product, your check points will vanish by turning off the assertions in deployment; no performance hit, no code removal work.<br />
<br />
>assertion statement is a little odd; when you assert on a condition, it gets activated only when the condition fails; activated in the sense, it throws AssertionError (yes Error, not Exception); so you can say, assertion raises alarm when one of your good old assumptions goes wrong :)<br />
<br />
>other way to say is "assert condition" is equavalent to saying "ensure/mandate this condition";<br />
that is make sure it is true!<br />
<br />
>assertions are off by default(the code will run as though there were no assert statements); application will not process assert statements unless otherwise you explicitly turn them on; pretty handy for development time, eh?<br />
<br />
>AssertionError is stop-the-world-for-good type; when your assert condition fails program exits then and there<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>private void doStuff()//flavor 1<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>assert(y>x);//ensure y>x<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//more code assuming y greater than x<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>private void doStuff()//flavor 2<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>assert (y>x) : "y=" + y + ", x=" + x;//adds more info to your AssertionError<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>//more code assuming y greater than x<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>}<br />
<br />
>assertions stick around in the code even in deployment but being ignored by JVM; if something goes wrong in deployment, you can turn assertions on, and start debugging at client site; pretty slick, huh?<br />
<br />
>Flavor 2: assert condition : value; //condition should be a boolean expression; value should resolve to a variable of primitive or object type so that toString() can be performed on it to print the description; other code statements are not allowed in place of 'value'<br />
<br />
>'assert' was not a keyword before 1.4; from 1.4 onwards you can't use it as an identifier(variable name); so, you can use 'assert' as a keyword or identifier, but not both(only when u have mix of old and new codes)<br />
<br />
>if you want to use assertions, you must enable it when you compile;<br />
<br />
For Java 1.4 Compiler:<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>javac -source 1.4 TestClass.java<br />
<br />
For Java 6 Compiler:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>>this compiler will use assertions by default; that is, it validates assert statements also; if you have used assert keyword as identifier somewhere, by default java 6 compiler will complain; in that case you should mention to the compiler that you are really compiling a very old version of source code like 1.3<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>javac -source 1.3 OldCode.java<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>>compilers don't allow use of assert keyword as identifier in 1.4 or later source codes<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>javac -source 1.4 TestClass.java<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>javac -source 5 TestClass.java<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>javac -source 6 TestClass.java //all of these produce compilation error when assert keyword is used as identifier<br />
<br />
Enabling Disabling Assertions at runtime<br />
-----------------------------------------<br />
<br />
Enabling: java -ea TestClass or java -enableassertions TestClass<br />
Disabling: java TestClass or java -da TestClass or java -disableassertions TestClass<br />
<br />
//assertions are disabled by default as shown above<br />
<br />
Selective enabling/disabling<br />
----------------------------<br />
you can selectively enable assertions for certain classes/packages alone.<br />
<br />
You just have to mention the class/package name along with -ea/-da switch. That's all.<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>java -ea:javax.swing TestClass (enables only for one package and its subpackages)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>java -ea -da:java.util.ArrayList TestClass (enables for all, but disables for one class)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
In the above example, assertions were enabled for javax.swing, and all other subpackages (like javax.swing.table, etc). But in general java doesn't treat any package as subpackage. For java javax.swing is a separate package from javax.swing.table; only here in the context of assertions we call them subpackages and have a way to address all of them together.<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>java -ea -dsa ===> enables assertions in general, but disables assertions in system classes<br />
<br />
Assertion use guideline<br />
-----------------------<br />
>though AssertionError is catchable(subtype of Throwable), never catch it; it defeats the purpose<br />
>to emphasize this, AssertionError doesn't provide access to the object that generated it(getCause() returns null)<br />
>using assert to validate input argument to a public method is inappropriate(it's part of your application logic you dummy, and also assertion is disabled by default, and user of your code will end up getting wrong behavior; so never rely on assert for application logic)<br />
>but still you can use assert to validate input arguments if the method is private; because you have control over the source code in this case and its usage as well<br />
>don't use assertion to validate command line arguments<br />
>for check point purposes you can use assert everywhere private or public<br />
>don't let your assert expressions (as part of condition or display msg expression) modify any state of your system/program which application logic depends on; because assert can be disabled and sure is, in deployment<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>e.g. assert(getCondition()); //getCondition() returns boolean but also alters application state before returning - dangerous!<br />
<br />
# It is not guaranteed that finally block would be called when try or catch block issues System.exit()<br />
<br />
# Assertion is a useful debugging tool<br />
<br />
# Exception in finally block can jeopardize it from executing completely<br />
<br />
# declaration is must in enhanced for loop; it can't use previously declared loop variable<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>int i=0;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>for(i : new int[]{1,2,3}{} //will not compile<br />
<br />
# infinite for/while loop will not cause stack overflow error, they will merely run forever(program hangs in there)<br />
<br />
# Program can continue after catching StackOverflowError (but may not work with OutOfMemoryError)<br />
<br />
# Assignment to a variable is allowed in the 2nd expression of assert statement (assert true : list=new ArrayList(); //compiles)<br />
<br />
<b>Reference: </b>Kathy Sierra's SCJP Book<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0tag:blogger.com,1999:blog-5659366926389737478.post-75542663806747182022012-05-05T06:58:00.000+05:302012-07-17T23:17:45.381+05:30GIST NOTES 4 - Java Operators<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<br />
<span style="font-size: x-large;">GIST NOTES 4 - Java Operators</span><br />
<br />
<span style="color: red;"><b>[DISCLAIMER: This is solely for non-commercial use. I don't claim ownership of this content. This is a crux of all my readings studies and analysis. Some of them are excerpts from famous books on the subject. Some of them are my contemplation upon experiments with direct hand coded code samples using IDE or notepad.</b></span><br />
<span style="color: red;"><b><br /></b></span><br />
<span style="color: red;"><b>I've created this mainly to reduce an entire book into few pages of critical content that we should never forget. Even after years, you don't need to read the entire book again to get back its philosophy. I hope these notes will help you to replay the entire book in your mind once again.]</b></span><br />
<br />
<br />
[JDK 7]<br />
<br />
operators produce new values from one or more operands.<br />
<br />
operands are the things that are on the left or right side of the operator.<br />
<br />
+ operator adds two primitive numbers together or concatenates string literals.<br />
<br />
&, | and ^ operators can be used in two different ways; one for logic another for binary operations.<br />
<br />
Assignment Operator<br />
-------------------<br />
<br />
When assigning value to a primitive, size matters.<br />
<br />
Pointers in C/C++ are physical memory locations.<br />
<br />
Object references in Java are logical IDs to an abstracted entity called object that lives in heap memory of the Virtual Machine. Nobody knows the physical memory locations the VM uses to store objects.<br />
<br />
Java DOES NOT have pointers.<br />
<br />
Compound Assignment Operators<br />
-----------------------------<br />
<br />
Like +=, -=, *= and /=.<br />
<br />
Expression on the right hand side of the compound operator will be evaluated first before employing compound operator.<br />
<br />
Relational Operators<br />
---------------------<br />
<br />
Relational operators always results in boolean value.<br />
<br />
Hence the resulting value can be used for conditionals or can be assigned to a boolean primitive variable.<br />
<br />
> >= < <= operators allow any combination of integers, floating point numbers or characters to be compared.<br />
<br />
Comparison between characters and between character and a number are all LEGAL in java (w.r.to relational operators mentioned above).<br />
<br />
Java uses unicode value of the character for comparison.<br />
<br />
Equality Operators (== and !=)<br />
------------------------------<br />
<br />
These two return boolean value as a result of comparison.<br />
<br />
One can't compare incompatible types.<br />
<br />
== looks at the bit pattern of the variables being compared.<br />
<br />
(5.0 == 5L) returns true.<br />
<br />
Using = in the place of == will lead to erraneous behaviour (though this confusion will occur only with boolean variables).<br />
<br />
== operator does not look inside the objects being compared.<br />
<br />
However when comparing enum constants(in object form), == does indeed finds out whether they are actually equal or not(enum constants are static objects, that is why).<br />
<br />
instanceof operator<br />
-------------------<br />
<br />
instanceof operator is used only for object reference variables.<br />
<br />
Lefthand side object should pass IS-A test for the right hand side type. e.g. ("hi" instanceof String) returns true.<br />
<br />
Usually instanceof check is done before doing a downcast to convert an object to one of its subtypes.<br />
<br />
Testing instanceof on a null is LEGAL.<br />
<br />
When two OBVIOUSLY unrelated types (even compiler knows you are STUPID) are compared with instanceof, compilation fails. e.g. ("hi" instanceof Thread) fails to compile. Basically types from two different class hierarchies are not allowed to be compared.<br />
<br />
( (new int[]{1,2}) instanceof Object ) returns true.<br />
<br />
Arithmetic Operators<br />
---------------------<br />
<br />
* / % operators have higher precedence than + or -.<br />
<br />
Concatenation<br />
-------------<br />
<br />
+ is used to concatenate string literals. Mixing numbers with at least one string variable results in all numbers involved in the expression be treated as strings, and a string concatenation is performed.<br />
<br />
e.g. ("hi" + 2 + score) results in a string<br />
<br />
+= operator also can be used for string concatenation.<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>int b=3;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(""+b+4); //prints 34<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println("1"+ (b+4) ); //prints 17<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(b+4); //prints 7<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>System.out.println(b+4+"6"); //prints 76 (this is because the expression is always evaluated<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span> //from left to right; so until a string variable is reached,it does numeric addition)<br />
<br />
Increment/Decrement Operators<br />
-----------------------------<br />
<br />
a++ value of 'a' is used in the expression before incrementing.<br />
<br />
++a value of 'a' is used in the expression after incrementing.<br />
<br />
Using these operators on a final variable results in compiler error.<br />
<br />
Conditional Operator<br />
--------------------<br />
<br />
It is called ternary operator. It has three operands.<br />
<br />
It is used to evaluate boolean expressions.<br />
<br />
Ternary operator decides which value to assign based on the condition.<br />
<br />
x = (condition) ? a : b; //if success 'a' is assigned, otherwise 'b' is assigned.<br />
<br />
Ternary operator can be nested.<br />
<br />
x = (condition1) ? a : (condition2) ? b : c;<br />
<br />
Logical Operators<br />
------------------<br />
<br />
They are [& | ^ ! && ||].<br />
<br />
& | ^ operators are also used for bitwise operations.<br />
<br />
& --> both bits should be 1<br />
| --> any one of the bits should be 1<br />
^ --> only one of the bits should be 1, but not both(XOR operation)<br />
<br />
Short circuit logical operators<br />
-------------------------------<br />
<br />
Short circuit AND is &&.<br />
<br />
Short circuit OR is ||.<br />
<br />
These are named short-circuit operators because they don't waste time on evaluating all parts of the boolean expression. Once end result is known they skip the remaining expressions and return the result.<br />
<br />
&& evaluates left side expression first and if it turns out to be 'false' it skips all right side expressions.<br />
<br />
cond1 && cond2 && cond3 - skips evaluating cond2 and cond3 if cond1 is false.<br />
<br />
|| evaluates left side expression first and if it is 'true' skips all right hand side expressions. Otherwise, it keeps evaluating till it gets 'true'.<br />
<br />
These two operators work only with boolean operands.<br />
<br />
if(5 && 1) {} will not compile.<br />
<br />
Non short circuit logical operators<br />
-----------------------------------<br />
<br />
They are | and &. They are exactly same as || and && except that they are dumb. That is they evaluate all operands even though the final result is evident early.<br />
<br />
NOT and XOR<br />
------------<br />
<br />
^ is exclusive OR and ! is boolean invert.<br />
<br />
These two operate only on boolean values. (heh? ^ can do bit XOR also right?)<br />
<br />
^ operator evaluates all operands and doesn't skip any expression. It returns true if only one operand is true out of the two.<br />
<br />
! returns the opposite of the operand at hand.<br />
<br />
Overloaded Operators<br />
--------------------<br />
<br />
+ can add numbers and concatenate strings; hence it is overloaded operator.<br />
<br />
| & ^ are used for bitwise operation as well as logical expressions; hence they are overloaded.<br />
<br />
<br />
Mathematical expressions are evaluated from left to right.<br />
<br />
<br />
String[] args = new String[0]; // it is possible to create an array of 0 size; args is not null and tyring to access args[0] will result in ArrayIndexOutOfBoundsException. This is happens when no command line paramenters are passed to main method.<br />
<br />
<br />
Reference: Kathy Sierra's SCJP Book<br />
<br /></div>Dobby Severus Salazarhttp://www.blogger.com/profile/02716356627351003762noreply@blogger.com0