พฤติกรรมที่ไม่ได้กำหนดใน Java


14

ฉันอ่านคำถามนี้เกี่ยวกับ SOที่กล่าวถึงพฤติกรรมที่ไม่ได้กำหนดทั่วไปใน C ++ และฉันสงสัยว่า: Java มีพฤติกรรมที่ไม่ได้กำหนดหรือไม่

หากเป็นเช่นนั้นแล้วสาเหตุทั่วไปของพฤติกรรมที่ไม่ได้กำหนดใน Java คืออะไร

ถ้าไม่เช่นนั้นคุณสมบัติใดของ Java ที่ทำให้ปราศจากพฤติกรรมดังกล่าวและเพราะเหตุใด C และ C ++ รุ่นล่าสุดจึงไม่ถูกนำไปใช้กับคุณสมบัติเหล่านี้


4
Java มีการกำหนดอย่างเข้มงวดมาก ตรวจสอบข้อกำหนดภาษา Java


4
@ user1249 "พฤติกรรมที่ไม่ได้กำหนด" ก็มีการกำหนดอย่างเข้มงวดเช่นกัน
Pacerier

เป็นไปได้เช่นเดียวกันกับ SO: stackoverflow.com/questions/376338/ …
Ciro Santilli 事件改造中心中心法轮功六四事件

Java พูดถึงอะไรเมื่อคุณละเมิด "สัญญา" เช่นเกิดขึ้นเมื่อคุณเกิน. เท่ากับจะไม่เข้ากันกับ. hashCode? docs.oracle.com/javase/7/docs/api/java/lang/… นั่นไม่ได้ระบุคำเรียกขาน แต่ไม่ได้ใช้เทคนิคในทางเดียวกันกับที่ C ++ เป็นหรือไม่?
Mooing Duck

คำตอบ:


18

ใน Java คุณสามารถพิจารณาพฤติกรรมของโปรแกรมที่ไม่ถูกต้องตรงกันได้

Java 7 JLS ใช้คำว่า "undefined" หนึ่งครั้งใน17.4.8 การประหารชีวิตและข้อกำหนดของเวรกรรม :

เราใช้f|dเพื่อแสดงถึงฟังก์ชั่นที่ได้รับจากการ จำกัด โดเมนของการf dสำหรับทั้งหมดxในd, f|d(x) = f(x)และทั้งหมดxไม่ได้อยู่ในd, f|d(x)มีการกำหนด ...

เอกสารคู่มือ Java API ระบุบางกรณีเมื่อผลลัพธ์ไม่ได้กำหนดตัวอย่างเช่นในวันที่ของตัวสร้าง (คัดค้าน) (ปี int, เดือน int, วัน int) :

ผลลัพธ์ไม่ได้ถูกกำหนดหากอาร์กิวเมนต์ที่กำหนดนั้นไม่อยู่ในขอบเขต ...

Javadocs สำหรับสถานะExecutorService.invokeAll (Collection) :

ผลลัพธ์ของวิธีนี้จะไม่ได้กำหนดหากมีการแก้ไขการรวบรวมในขณะที่การดำเนินการนี้กำลังดำเนินการ ...

พฤติกรรมที่เป็นทางการน้อยลงของ "ไม่ได้กำหนด" สามารถพบได้ในConcurrentModificationExceptionซึ่งเอกสาร API ใช้คำว่า "พยายามอย่างดีที่สุด":

โปรดทราบว่าพฤติกรรมที่ล้มเหลวอย่างรวดเร็วไม่สามารถรับประกันได้ว่าเป็นไปไม่ได้ที่จะทำการค้ำประกันอย่างหนักเมื่อมีการปรับเปลี่ยนพร้อมกันที่ไม่ซิงโครไนซ์ การดำเนินการล้มเหลวอย่างรวดเร็วโยนConcurrentModificationExceptionในที่ดีที่สุดความพยายามพื้นฐาน ดังนั้นมันจะผิดที่จะเขียนโปรแกรมที่ขึ้นอยู่กับข้อยกเว้นนี้สำหรับความถูกต้องของมัน ...


ภาคผนวก

หนึ่งในคำถามที่ความคิดเห็นหมายถึงบทความโดยเอริค Lippert ซึ่งมีการแนะนำที่เป็นประโยชน์ลงไปในเรื่องหัวข้อ: การพฤติกรรมการดำเนินงานที่กำหนดไว้

ฉันแนะนำบทความนี้สำหรับเหตุผลเกี่ยวกับภาษาซึ่งไม่เชื่อเรื่องพระเจ้าถึงแม้ว่ามันจะคุ้มค่าที่จะจำไว้ว่าผู้เขียนมีเป้าหมายเป็น C # ไม่ใช่ Java

ตามเนื้อผ้าเราบอกว่าสำนวนภาษาการเขียนโปรแกรมมีพฤติกรรมที่ไม่ได้กำหนดหากการใช้สำนวนนั้นสามารถมีผลกระทบใด ๆ ; สามารถทำงานได้ตามที่คุณคาดหวังหรือสามารถลบฮาร์ดดิสก์ของคุณหรือทำให้เครื่องเสียหาย นอกจากนี้ผู้เขียนคอมไพเลอร์ไม่มีข้อผูกมัดที่จะเตือนคุณเกี่ยวกับพฤติกรรมที่ไม่ได้กำหนด (และในความเป็นจริงมีบางภาษาที่โปรแกรมที่ใช้สำนวน "พฤติกรรมที่ไม่ได้กำหนด" ได้รับอนุญาตจากข้อกำหนดภาษาเพื่อคอมไพเลอร์!) ...

ในทางตรงกันข้ามสำนวนที่มีพฤติกรรมที่กำหนดโดยการนำไปใช้นั้นเป็นพฤติกรรมที่ผู้เขียนคอมไพเลอร์มีหลายทางเลือกเกี่ยวกับวิธีการนำคุณลักษณะไปใช้และต้องเลือกอย่างใดอย่างหนึ่ง อย่างที่ชื่อบ่งบอกว่าพฤติกรรมที่กำหนดโดยการนำไปปฏิบัตินั้นมีการกำหนดไว้อย่างน้อยที่สุด ตัวอย่างเช่น C # อนุญาตให้มีการใช้งานเพื่อโยนข้อยกเว้นหรือสร้างมูลค่าเมื่อการหารจำนวนเต็มล้น แต่การใช้งานจะต้องเลือกหนึ่ง ไม่สามารถลบฮาร์ดดิสก์ของคุณ ...

อะไรคือปัจจัยบางอย่างที่ทำให้คณะกรรมการออกแบบภาษาปล่อยให้สำนวนภาษาบางอย่างเป็นพฤติกรรมที่ไม่ได้กำหนดไว้หรือการใช้งานที่กำหนดไว้

ปัจจัยสำคัญอันดับแรกคือ: มีการใช้งานของสองภาษาที่มีอยู่ในตลาดที่ไม่เห็นด้วยกับพฤติกรรมของโปรแกรมเฉพาะหรือไม่ ...

ปัจจัยสำคัญต่อไปคือ: คุณสมบัตินี้นำเสนอความเป็นไปได้ที่แตกต่างกันหลายประการสำหรับการนำไปใช้งานจริงหรือไม่ซึ่งบางอย่างดีกว่าอย่างอื่นหรือไม่? ...

ปัจจัยที่สามคือ: คุณสมบัติซับซ้อนหรือไม่ที่รายละเอียดของพฤติกรรมที่แน่นอนนั้นยากหรือแพง ...

ปัจจัยที่สี่คือ: ฟีเจอร์กำหนดภาระสูงให้คอมไพเลอร์วิเคราะห์หรือไม่? ...

ปัจจัยที่ห้าคือ: คุณลักษณะนี้ทำให้เกิดภาระสูงในสภาพแวดล้อมรันไทม์หรือไม่? ...

ปัจจัยที่หกคือ: การกำหนดพฤติกรรมทำให้มีการเพิ่มประสิทธิภาพที่สำคัญหรือไม่? ...

เหล่านี้เป็นเพียงไม่กี่ปัจจัยที่มาถึงใจ; แน่นอนว่ามีปัจจัยอื่น ๆ อีกมากมายที่คณะกรรมการออกแบบภาษาโต้เถียงกันก่อนที่จะสร้างคุณลักษณะ "การนำไปปฏิบัติที่กำหนด" หรือ "ไม่ได้กำหนด"

ข้างต้นเป็นเพียงความคุ้มครองสั้น ๆ ; บทความเต็มมีคำอธิบายและตัวอย่างสำหรับจุดที่กล่าวถึงในข้อความที่ตัดตอนมานี้; มันเป็นมากมูลค่าการอ่าน ตัวอย่างเช่นรายละเอียดที่ให้ไว้สำหรับ "ปัจจัยที่หก" สามารถให้ข้อมูลเชิงลึกเกี่ยวกับแรงจูงใจสำหรับข้อความมากมายใน Java Memory Model ( JSR 133 ) ช่วยให้เข้าใจว่าเหตุใดการเพิ่มประสิทธิภาพบางอย่างจึงได้รับอนุญาตนำไปสู่พฤติกรรมที่ไม่ได้กำหนด ข้อ จำกัด ชอบเกิดขึ้นมาก่อนและความต้องการของเวรกรรม

ไม่มีบทความใดที่เป็นเนื้อหาใหม่สำหรับฉัน แต่ฉันจะถูกประณามถ้าฉันเคยเห็นมันนำเสนอในรูปแบบที่สวยงามสุภาพและเข้าใจง่าย น่าอัศจรรย์


ฉันจะเพิ่ม JMM! = ฮาร์ดแวร์พื้นฐานและผลลัพธ์สุดท้ายของโปรแกรมที่ดำเนินการเกี่ยวกับการทำงานพร้อมกันอาจแตกต่างจากการพูด WinIntel กับ Solaris
Martijn Verburg

2
@ MartijnVerburg เป็นจุดที่ดีงาม เหตุผลเดียวที่ผมลังเลที่จะแท็กว่า "ไม่ได้กำหนด" คือว่าข้อ จำกัด ของหน่วยความจำแบบโพสท่าชอบเกิดขึ้นมาก่อนและอำนาจในการดำเนินการของโปรแกรมซิงค์อย่างถูกต้อง
ริ้น

ทรูสเปคกำหนดวิธีการที่ควรปฏิบัติตนภายใต้ JMM แต่ Intel et al, ไม่เคยเห็นด้วย ;-)
Martijn Verburg

@ MartijnVerburg ฉันคิดว่าประเด็นหลักของ JMM คือการป้องกันการรั่วไหลที่เกิดจากผู้ผลิตโปรเซสเซอร์ที่ไม่เห็นด้วย เท่าที่ฉันเข้าใจ Java ก่อน 5.0 มีอาการปวดหัวแบบนี้กับ DEC Alpha เมื่อการเขียนเชิงเก็งกำไรภายใต้ประทุนสามารถรั่วไหลลงในโปรแกรมเช่น "ออกมาจากอากาศบาง" - ดังนั้นความต้องการสาเหตุได้เข้าสู่ JSR 133 (JMM)
gnat

9
@MartinVerburg - เป็นงานของผู้ดำเนินการ JVM เพื่อให้แน่ใจว่า JVM ทำงานตามข้อกำหนด JLS / JMM บนแพลตฟอร์มฮาร์ดแวร์ใด ๆ ที่รองรับ หากฮาร์ดแวร์ที่แตกต่างกันทำงานแตกต่างกันมันเป็นหน้าที่ของผู้ดำเนินการ JVM ในการจัดการกับมัน ... และทำให้มันใช้งานได้
Stephen C

10

จากด้านบนของหัวของฉันฉันไม่คิดว่าจะมีพฤติกรรมที่ไม่ได้กำหนดใน Java อย่างน้อยก็ไม่ได้อยู่ในความรู้สึกเช่นเดียวกับใน C ++

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

ในทางตรงกันข้ามเป้าหมายหลักในการออกแบบของ C และ C ++ คือประสิทธิภาพ: ไม่ควรมีคุณสมบัติใด ๆ (รวมถึงความเป็นอิสระของแพลตฟอร์ม) ที่มีประสิทธิภาพด้านต้นทุนแม้ว่าคุณจะไม่ต้องการก็ตาม ด้วยเหตุนี้สเปคที่ตั้งใจไม่ได้กำหนดพฤติกรรมบางอย่างเพราะการกำหนดพวกเขาจะทำให้การทำงานพิเศษในบางแพลตฟอร์มและลดประสิทธิภาพแม้สำหรับผู้ที่เขียนโปรแกรมเฉพาะสำหรับแพลตฟอร์มเดียวและตระหนักถึงนิสัยของมันทั้งหมด

มีแม้กระทั่งตัวอย่างที่ Java ถูกบังคับให้นำพฤติกรรมที่ไม่ได้กำหนดในแบบย้อนหลังกลับมาให้เหตุผลย้อนหลัง: คำสำคัญที่เข้มงวดได้ถูกนำมาใช้ใน Java 1.2 เพื่อให้การคำนวณจุดลอยตัวเบี่ยงเบนจากการปฏิบัติตามมาตรฐาน IEEE 754 อย่างแน่นอน เนื่องจากการทำเช่นนั้นจำเป็นต้องใช้งานพิเศษและทำให้การคำนวณจำนวนจุดลอยตัวทั้งหมดช้าลงบน CPU ทั่วไปบางตัวในขณะที่ผลลัพธ์ที่แย่กว่านั้นในบางกรณี


2
ฉันคิดว่ามันสำคัญที่จะต้องทราบเป้าหมายหลักอื่น ๆ ของ Java: ความปลอดภัยและความโดดเดี่ยว ฉันคิดว่านี่ก็เป็นเหตุผลสำหรับการขาดพฤติกรรม 'ไม่ได้กำหนด' (เช่นใน C ++)
K.Steff

3
@ K.Steff: Hyper-modern C / C ++ เหมาะสำหรับความปลอดภัยที่เกี่ยวข้องกับระยะไกล การกำหนดint x=-1; foo(); x<<=1;ปรัชญาที่ทันสมัยเกินจะเอื้อต่อการเขียนใหม่fooเพื่อให้เส้นทางที่ไม่ออกจะต้องไม่สามารถเข้าถึงได้ นี้ถ้าfooเป็นif (should_launch_missiles) { launch_missiles(); exit(1); }คอมไพเลอร์สามารถ (และตามที่บางคน) launch_missiles(); exit(1);ควรลดความซับซ้อนที่จะเพียงแค่ UB ดั้งเดิมคือการใช้รหัสแบบสุ่ม แต่เคยถูกผูกมัดโดยกฎหมายของเวลาและเวรกรรม UB ที่ปรับปรุงใหม่ถูกผูกมัดโดยไม่
supercat

3

Java พยายามอย่างหนักเพื่อกำจัดพฤติกรรมที่ไม่ได้กำหนดเนื่องจากบทเรียนของภาษาก่อนหน้านี้ ตัวอย่างเช่นตัวแปรระดับชั้นจะเริ่มต้นโดยอัตโนมัติ ตัวแปรโลคัลไม่ได้ถูกกำหนดค่าเริ่มต้นโดยอัตโนมัติด้วยเหตุผลด้านประสิทธิภาพ แต่มีการวิเคราะห์การไหลของข้อมูลที่ซับซ้อนเพื่อป้องกันไม่ให้ทุกคนเขียนโปรแกรมที่สามารถตรวจจับสิ่งนี้ได้ การอ้างอิงไม่ใช่ตัวชี้ดังนั้นจึงไม่มีการอ้างอิงที่ไม่ถูกต้องและการอ้างอิงnullซ้ำทำให้เกิดข้อยกเว้นเฉพาะ

แน่นอนว่ายังมีพฤติกรรมบางอย่างที่ไม่ได้ระบุอย่างสมบูรณ์และคุณสามารถเขียนโปรแกรมที่ไม่น่าเชื่อถือหากคุณคิดว่าเป็น ตัวอย่างเช่นหากคุณทำซ้ำมากกว่าปกติ (ไม่เรียงลำดับ) Setภาษารับประกันว่าคุณจะเห็นแต่ละองค์ประกอบอย่างแน่นอนหนึ่งครั้ง แต่ไม่เรียงตามลำดับที่คุณจะเห็น คำสั่งซื้ออาจเหมือนกันในการรันต่อเนื่องหรืออาจมีการเปลี่ยนแปลง หรือมันอาจยังคงอยู่ตราบใดที่ไม่มีการจัดสรรอื่นเกิดขึ้นหรือตราบใดที่คุณไม่ได้อัพเดต JDK ของคุณ ฯลฯ มันเป็นไปไม่ได้เลยที่จะกำจัดผลกระทบดังกล่าวทั้งหมด ตัวอย่างเช่นคุณจะต้องสั่งหรือสุ่มการดำเนินการของคอลเลกชันทั้งหมดอย่างชัดเจนและนั่นก็ไม่คุ้มค่ากับสิ่งเล็ก ๆ ที่ไม่ได้กำหนดเพิ่มเติม


อ้างอิงเป็นตัวชี้ภายใต้ชื่ออื่น
curiousguy

@curtguy - "การอ้างอิง" โดยทั่วไปถือว่าไม่อนุญาตให้ใช้การคำนวณทางคณิตศาสตร์ของค่าตัวเลขซึ่งมักจะได้รับอนุญาตสำหรับ "พอยน์เตอร์" ดังนั้นอดีตจึงเป็นโครงสร้างที่ปลอดภัยกว่าแบบหลัง รวมกับระบบการจัดการหน่วยความจำที่ไม่อนุญาตให้มีการใช้พื้นที่เก็บข้อมูลของวัตถุในขณะที่มีการอ้างอิงที่ถูกต้องอยู่การอ้างอิงป้องกันหน่วยความจำใช้ข้อผิดพลาด พอยน์เตอร์ไม่สามารถทำได้แม้ว่าจะใช้การจัดการหน่วยความจำที่เหมาะสมก็ตาม
จูลส์

@Jules จากนั้นเป็นเรื่องของคำศัพท์: คุณอาจเรียกตัวชี้หรือสิ่งอ้างอิงและตัดสินใจใช้ "การอ้างอิง" ใน "ปลอดภัย" ภาษาและ "ตัวชี้" ในภาษาที่อนุญาตให้ใช้การคำนวณทางคณิตศาสตร์และการจัดการหน่วยความจำด้วยตนเอง (AFAIK "คำนวณตัวชี้" จะทำเฉพาะใน C / C ++.)
curiousguy

2

คุณต้องเข้าใจ "พฤติกรรมที่ไม่ได้กำหนด" และที่มาของมัน

พฤติกรรมที่ไม่ได้กำหนดหมายถึงพฤติกรรมที่ไม่ได้กำหนดโดยมาตรฐาน C / C ++ มีการใช้งานคอมไพเลอร์ที่แตกต่างกันมากเกินไปและคุณสมบัติเพิ่มเติม คุณสมบัติเพิ่มเติมเหล่านี้ผูกรหัสกับคอมไพเลอร์ เนื่องจากไม่มีการพัฒนาภาษาแบบรวมศูนย์ ดังนั้นคุณสมบัติขั้นสูงบางอย่างของคอมไพเลอร์บางตัวจึงกลายเป็น "พฤติกรรมที่ไม่ได้กำหนด"

ในขณะที่ Java มีการควบคุมข้อกำหนดภาษาโดย Sun-Oracle และไม่มีใครพยายามกำหนดรายละเอียดและไม่มีพฤติกรรมที่ไม่ได้กำหนด

แก้ไขโดยเฉพาะการตอบคำถาม

  1. Java เป็นอิสระจากพฤติกรรมที่ไม่ได้กำหนดเนื่องจากมาตรฐานถูกสร้างขึ้นก่อนคอมไพเลอร์
  2. คอมไพเลอร์ C / C ++ ที่ทันสมัยมีการใช้งานที่เป็นมาตรฐานมากขึ้น / น้อยลง แต่คุณสมบัติที่นำมาใช้ก่อนที่มาตรฐานจะยังคงติดแท็กเป็น "พฤติกรรมที่ไม่ได้กำหนด" เพราะ ISO เก็บแม่ไว้ในประเด็นเหล่านี้

2
คุณอาจถูกต้องว่าไม่มี UB ใน Java แต่แม้ว่าเอนทิตีหนึ่งจะควบคุมทุกอย่างอาจมีเหตุผลที่จะมี UB ดังนั้นเหตุผลที่คุณให้ไม่ได้นำไปสู่ข้อสรุป
AProgrammer

2
นอกจากนี้ทั้ง C และ C ++ ได้มาตรฐานโดย ISO แม้ว่าอาจจะมีคอมไพเลอร์หลายตัว แต่ก็มีเพียงหนึ่งมาตรฐานในแต่ละครั้ง
MSalters

1
@ SarvexJatasra ฉันไม่เห็นด้วยว่าเป็นแหล่งเดียวของ UB ตัวอย่างเช่นหนึ่ง UB กำลังยกเลิกการลงทะเบียนตัวชี้ห้อยและมีเหตุผลที่ดีที่จะปล่อย UB ในภาษาใด ๆ ที่ไม่มี GC แม้ว่าคุณจะเริ่มสเป็คตอนนี้ และเหตุผลเหล่านั้นไม่เกี่ยวข้องกับการปฏิบัติที่มีอยู่หรือคอมไพเลอร์ที่มีอยู่
AProgrammer

2
@SarvexJatasra การโอเวอร์โฟลว์ที่ลงนามแล้วคือ UB เนื่องจากมาตรฐานระบุอย่างชัดเจนดังนั้น (แม้เป็นตัวอย่างที่ให้มาพร้อมกับคำจำกัดความของ UB) การอ้างอิงตัวชี้ที่ไม่ถูกต้องเป็น UB ด้วยเหตุผลเดียวกันมาตรฐานกล่าวเช่นนั้น
AProgrammer

2
@ bames53: ไม่มีข้อได้เปรียบที่อ้างถึงจะต้องใช้ระดับของคอมไพเลอร์ hypermodern ละติจูดที่ใช้กับ UB ด้วยข้อยกเว้นของการเข้าถึงหน่วยความจำนอกและขอบเขตล้นซึ่งสามารถ "กระตุ้น" การสุ่มรหัสฉันไม่สามารถคิดถึงการเพิ่มประสิทธิภาพที่มีประโยชน์ซึ่งจะต้องใช้ละติจูดที่กว้างกว่าที่จะบอกว่าการดำเนินการของ UB-ish ส่วนใหญ่ไม่แน่นอน ค่า (ซึ่งอาจทำงานเหมือนว่าพวกเขามี "บิตพิเศษ") และอาจมีผลกระทบเกินกว่านั้นหากเอกสารของการดำเนินงานขอสงวนสิทธิ์ที่จะกำหนดเช่นนั้นอย่างชัดแจ้ง; เอกสารอาจให้ "พฤติกรรมที่ไม่ จำกัด " ...
Supercat

1

Java กำจัดพฤติกรรมที่ไม่ได้กำหนดเป็นหลักที่พบใน C / C ++ (ตัวอย่างเช่น: จำนวนเต็มล้นลงนามหารด้วยศูนย์ตัวแปร uninitialized ตัวชี้โมฆะตัวชี้โมฆะมากกว่าความกว้างของบิตฟรีสองครั้งแม้ "ไม่มีการขึ้นบรรทัดใหม่ในตอนท้ายของซอร์สโค้ด") แต่จาวามีพฤติกรรมที่ไม่ได้กำหนดไว้อย่างชัดเจน โปรแกรมเมอร์มักไม่ค่อยพบ

  • Java Native Interface (JNI) เป็นวิธีสำหรับ Java ในการเรียกรหัส C หรือ C ++ มีหลายวิธีในการทำให้ล้มเหลวใน JNI เช่นการทำให้ลายเซ็นของฟังก์ชันไม่ถูกต้องการโทรไปยังบริการ JVM ไม่ถูกต้องการทำลายหน่วยความจำการจัดสรร / การปล่อยสิ่งที่ไม่ถูกต้องและอื่น ๆ ฉันเคยทำผิดพลาดมาก่อนและโดยทั่วไป JVM ทั้งหมดล้มเหลวเมื่อมีเธรดใดที่เรียกใช้งานรหัส JNI ยอมรับข้อผิดพลาด

  • Thread.stop()ซึ่งเลิกใช้แล้ว อ้างถึง:

    ทำไม Thread.stopเลิกใช้แล้ว

    เพราะมันไม่ปลอดภัยโดยเนื้อแท้ การหยุดเธรดทำให้ต้องปลดล็อกจอภาพทั้งหมดที่ล็อคไว้ (จอภาพถูกปลดล็อกเนื่องจากThreadDeathข้อยกเว้นแพร่กระจายสแต็ก) หากวัตถุใด ๆ ที่ป้องกันก่อนหน้านี้โดยจอภาพเหล่านี้อยู่ในสถานะไม่สอดคล้องกันเธรดอื่น ๆ อาจดูวัตถุเหล่านี้ในสถานะไม่สอดคล้องกัน วัตถุดังกล่าวได้รับความเสียหาย เมื่อเธรดทำงานบนวัตถุที่เสียหายพฤติกรรมการทำงานตามอำเภอใจอาจส่งผลให้ พฤติกรรมนี้อาจบอบบางและตรวจจับได้ยากหรืออาจเด่นชัด ไม่เหมือนกับข้อยกเว้นอื่น ๆ ที่ไม่ได้ตรวจสอบThreadDeathฆ่ากระทู้อย่างเงียบ ๆ ดังนั้นผู้ใช้จึงไม่มีคำเตือนว่าโปรแกรมของเขาอาจเสียหาย การคอร์รัปชั่นสามารถปรากฏตัวได้ตลอดเวลาหลังจากความเสียหายที่เกิดขึ้นจริงแม้กระทั่งชั่วโมงหรือวันในอนาคต

    https://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

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