ตัวดัดแปลงชั่วคราวและสารระเหยคืออะไร?


126

ใครช่วยอธิบายความหมายtransientและโมดิvolatileฟายเออร์ใน Java ได้บ้าง


3
เห็นได้ชัดว่านี่ไม่ใช่คำถามและนี่ก็ซ้ำกันอยู่ดี (ซึ่งเป็นสาเหตุที่ฉันโหวตให้ปิด) ดูตัวอย่างเหตุใด Java จึงมีตัวแปรชั่วคราว และคุณใช้คีย์เวิร์ดระเหยใน Java เมื่อใด (และอื่น ๆ อีกมากมาย)
Pascal Thivent

เป็นไปได้ที่ซ้ำกันสำหรับสิ่งที่ใช้ "ระเหย"?
Jeff

18
นี่เป็นคำถามที่ถูกต้องสมบูรณ์เทียบเท่ากับ: stackoverflow.com/questions/215497/…
Barry Fruitman

คำตอบ:


156

volatileและโมดิtransientฟายเออร์สามารถใช้ได้กับฟิลด์ของคลาส1โดยไม่คำนึงถึงประเภทฟิลด์ นอกเหนือจากนั้นไม่เกี่ยวข้องกัน

โมดิtransientฟายเออร์จะบอกให้ระบบย่อยการทำให้เป็นอนุกรมอ็อบเจ็กต์ Java ยกเว้นฟิลด์เมื่อทำให้อนุกรมอินสแตนซ์ของคลาส เมื่อวัตถุถูก deserialized แล้วฟิลด์จะเริ่มต้นเป็นค่าเริ่มต้น เช่นnullสำหรับประเภทการอ้างอิงและศูนย์หรือfalseสำหรับประเภทดั้งเดิม หมายเหตุว่า JLS (ดู8.3.1.3 ) ไม่ได้พูดในสิ่งที่transientหมายถึง แต่คล้อยตามกับวัตถุ Java เป็นอันดับจำเพาะ กลไกการทำให้เป็นอนุกรมอื่น ๆอาจให้ความสำคัญกับความtransient-ness ของสนาม หรืออาจเพิกเฉย

(โปรดทราบว่า JLS อนุญาตให้ประกาศstaticเขตข้อมูลเป็นtransientชุดค่าผสมนี้ไม่เหมาะสมสำหรับ Java Object Serialization เนื่องจากไม่ได้ทำให้เป็นอนุกรมสถิติอย่างไรก็ตามอาจสมเหตุสมผลในบริบทอื่น ๆ ดังนั้นจึงมีเหตุผลบางประการสำหรับ ไม่ห้ามทันที)

volatileปรับปรุงบอก JVM ที่เขียนไปยังเขตข้อมูลควรได้รับการล้างพร้อมกับหน่วยความจำและที่อ่านของสนามควรอ่านเสมอจากหน่วยความจำ ซึ่งหมายความว่าช่องที่ทำเครื่องหมายว่าระเหยสามารถเข้าถึงได้อย่างปลอดภัยและอัปเดตในแอปพลิเคชันแบบหลายเธรดโดยไม่ต้องใช้การซิงโครไนซ์ไลบรารีแบบเนทีฟหรือแบบมาตรฐาน ในทำนองเดียวกันการอ่านและเขียนไปยังเขตข้อมูลที่ระเหยได้นั้นเป็นปรมาณู (นี้ไม่ได้นำไปใช้กับ >> ไม่ระเหย << longหรือdoubleสาขาซึ่งอาจจะมีคำว่า "ฉีก" ในบาง JVMs.) ส่วนที่เกี่ยวข้องของ JLS เป็น8.3.1.4 , 17.4และ17.7


1 - แต่ไม่ใช่ตัวแปรโลคัลหรือพารามิเตอร์


10

volatileและtransientคำหลัก

1) transientคำหลักถูกใช้ร่วมกับตัวแปรอินสแตนซ์เพื่อแยกออกจากกระบวนการทำให้เป็นอนุกรม หากเขตข้อมูลเป็นtransientค่าจะไม่คงอยู่

ในทางกลับกันvolatileคำหลักจะใช้เพื่อทำเครื่องหมายตัวแปร Java ว่า "ถูกเก็บไว้ในหน่วยความจำหลัก"

การอ่านvolatileตัวแปรทุกครั้งจะอ่านจากหน่วยความจำหลักของคอมพิวเตอร์ไม่ใช่จากแคชของ CPU และการเขียนทุกvolatileตัวแปรจะถูกเขียนไปยังหน่วยความจำหลักไม่ใช่เฉพาะในแคชของ CPU

2) transientคำหลักไม่สามารถใช้ร่วมกับstaticคำหลัก แต่สามารถนำมาใช้พร้อมกับvolatilestatic

3) transientตัวแปรจะเริ่มต้นด้วยค่าเริ่มต้นในระหว่างการลดอนุกรมและการกำหนดหรือการคืนค่าจะต้องได้รับการจัดการโดยรหัสแอปพลิเคชัน

สำหรับข้อมูลเพิ่มเติมโปรดดูบล็อกของฉัน:
http://javaexplorer03.blogspot.in/2015/07/difference-between-volatile-and.html


2
เหตุผลที่transientไม่สามารถใช้ตัวแปรร่วมกับstaticคีย์เวิร์ดได้คือตัวแปรคงที่เป็นของคลาสไม่ใช่ของแต่ละอินสแตนซ์ แนวคิดของการทำให้เป็นอนุกรมเกี่ยวข้องกับสถานะปัจจุบันของวัตถุ เฉพาะข้อมูลที่เชื่อมโยงกับอินสแตนซ์เฉพาะของคลาสเท่านั้นที่ถูกทำให้เป็นอนุกรมดังนั้นฟิลด์สมาชิกแบบคงที่จะถูกละเว้นระหว่างการทำให้เป็นอนุกรม
Chaklader Asfak Arefe

ที่จริง JLS อนุญาตstaticและtransientให้ใช้ร่วมกันได้ ปัญหาคือมันสมเหตุสมผลน้อยเพราะกลไกการทำให้เป็นอนุกรมโดยทั่วไปไม่คงสถิตอยู่แล้ว
Stephen C

7

Volatile หมายถึงเธรดอื่น ๆ สามารถแก้ไขตัวแปรนั้นได้ ดังนั้นคอมไพเลอร์จึงอนุญาตให้เข้าถึงได้

http://www.javamex.com/tutorials/synchronization_volatile.shtml

ชั่วคราวหมายความว่าเมื่อคุณทำให้เป็นอนุกรมวัตถุวัตถุนั้นจะส่งคืนค่าเริ่มต้นในการยกเลิกการทำให้เป็นอนุกรม

http://www.geekinterview.com/question_details/2


5
"ดังนั้นคอมไพเลอร์จึงอนุญาตให้เข้าถึงได้" ประโยคของคุณแนะนำว่าเธรดไม่มีการเข้าถึงโดยค่าเริ่มต้น ตอนนี้ฉันอ่านลิงก์และคำตอบอื่น ๆ ที่ฉันเข้าใจ: คอมไพเลอร์ไม่ได้ทำการจัดเก็บตัวแปรกลางเฉพาะเธรดใด ๆ เพื่อให้เธรดอื่น ๆ สามารถเห็นการเปลี่ยนแปลงได้ทันที
helios

ฉันได้รับการใช้ C ของการระเหยและการใช้ java ของความสับสนวุ่นวาย ฉันหมายถึงคอมไพลเลอร์ทำให้มั่นใจได้ว่ามีการเข้าถึงค่าแอคทอลของฟิลด์แทนที่จะเป็นค่าแคช
Raynos

มันมีความหมายมากกว่านั้น
Stephen C

1

ชั่วคราว:

ก่อนอื่นต้องรู้ว่าจำเป็นต้องเชื่อมช่องว่างอย่างไร

1) ตัวปรับเปลี่ยนการเข้าถึงชั่วคราวใช้ได้กับส่วนประกอบตัวแปรเท่านั้น จะไม่ใช้กับ method หรือ class

2) ไม่สามารถใช้คีย์เวิร์ดชั่วคราวร่วมกับคีย์เวิร์ดแบบคงที่ได้

3) การทำให้เป็นอนุกรมคืออะไรและใช้ที่ไหน? การทำให้เป็นอนุกรมเป็นกระบวนการทำให้สถานะของวัตถุคงอยู่ นั่นหมายถึงสถานะของอ็อบเจ็กต์ถูกแปลงเป็นสตรีมไบต์เพื่อใช้ในการคงอยู่ (เช่นการจัดเก็บไบต์ในไฟล์) หรือการถ่ายโอน (เช่นการส่งไบต์ข้ามเครือข่าย) ในทำนองเดียวกันเราสามารถใช้ deserialization เพื่อดึงสถานะของวัตถุกลับมาจากไบต์ นี่เป็นแนวคิดที่สำคัญอย่างหนึ่งในการเขียนโปรแกรม Java เนื่องจากการทำให้เป็นอนุกรมส่วนใหญ่ใช้ในการเขียนโปรแกรมระบบเครือข่าย อ็อบเจ็กต์ที่ต้องการส่งผ่านเครือข่ายจะต้องถูกแปลงเป็นไบต์ ก่อนที่จะเข้าใจคำหลักชั่วคราวเราต้องเข้าใจแนวคิดของการทำให้เป็นอนุกรม หากผู้อ่านทราบเกี่ยวกับการทำให้เป็นอนุกรมโปรดข้ามจุดแรกไป

หมายเหตุ 1) Transient ส่วนใหญ่ใช้สำหรับกระบวนการ serialzation สำหรับคลาสนั้นจะต้องใช้อินเทอร์เฟซ java.io.Serializable ฟิลด์ทั้งหมดในคลาสต้องต่ออนุกรมกันได้ หากฟิลด์ไม่สามารถทำให้เป็นอนุกรมได้จะต้องทำเครื่องหมายชั่วคราว

หมายเหตุ 2) เมื่อกระบวนการ deserialized เกิดขึ้นพวกเขาจะได้รับการตั้งค่าเป็นค่าเริ่มต้น - ศูนย์เท็จหรือว่างตามข้อ จำกัด ประเภท

หมายเหตุ 3) คำสำคัญชั่วคราวและวัตถุประสงค์? ฟิลด์ที่ประกาศด้วยโมดิฟายเออร์ชั่วคราวจะไม่มีส่วนร่วมในกระบวนการต่อเนื่อง เมื่ออ็อบเจ็กต์ถูกทำให้เป็นอนุกรม (บันทึกในสถานะใด ๆ ) ค่าของฟิลด์ชั่วคราวของมันจะถูกละเว้นในการแสดงอนุกรมในขณะที่ฟิลด์อื่นที่ไม่ใช่ฟิลด์ชั่วคราวจะมีส่วนในกระบวนการทำให้เป็นอนุกรม นั่นคือจุดประสงค์หลักของคีย์เวิร์ดชั่วคราว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.