การมองเห็นการทำงานพร้อมกันของ Java

ฉันมีคำถามเกี่ยวกับการมองเห็นใน java การมองเห็นสามารถปรากฏได้ก็ต่อเมื่อเรามีอย่างน้อยสองเธรดซึ่งทำงานบนคอร์ซีพียูอย่างน้อย 2 คอร์ ใช่มั้ยล่ะ? ทุกคอร์สามารถแคชตัวแปรในรีจิสเตอร์และหน่วยความจำแคชได้ และเนื่องจากปัญหาการมองเห็นนั้นจึงอาจปรากฏขึ้นได้ แต่จะเป็นอย่างไรถ้าเรามี n เธรดและเธรดทั้งหมดทำงานใน cpu core ตัวเดียว (แน่นอนว่าเราไม่สามารถแน่ใจได้ว่าเธรดเหล่านั้นจะทำงานบน 1 คอร์เท่านั้น แต่สมมติว่าเป็นไปได้ที่จะบรรลุเป้าหมายนั้น) ไม่มีทางที่จะ มีการมองเห็นความทรงจำไหม? หรือนี่ไม่ถูกต้อง? ขอบคุณล่วงหน้า.


person DPM    schedule 29.07.2015    source แหล่งที่มา
comment
คุณหมายถึงอะไรโดยการมองเห็นหน่วยความจำ?   -  person ControlAltDel    schedule 29.07.2015
comment
เธรดหนึ่งที่ต้องเปลี่ยนตัวแปรและเธรดอื่นไม่เห็นการเปลี่ยนแปลงนี้ ขออภัยถ้าฉันไม่ได้ใช้คำศัพท์ที่ถูกต้อง   -  person DPM    schedule 29.07.2015
comment
ฉันไม่รู้คำตอบ แต่ต้องถาม: มันสร้างความแตกต่างอะไร? หากคุณได้เรียนรู้ว่าโปรแกรมแบบมัลติเธรดที่ทำงานบนเครื่องแบบ single-core จะไม่ได้รับผลกระทบจากข้อบกพร่องที่เกิดขึ้นพร้อมกันในลักษณะเดียวกับที่เกิดขึ้นเมื่อทำงานบนหลายคอร์ คุณจะเขียนโค้ดแบบ buggy ต่อไปหรือไม่ ฉันไม่รู้เกี่ยวกับโปรเซสเซอร์และการใช้งาน JVM มากพอ แต่ถึงแม้ในคอร์เดียว ดูเหมือนว่าข้อมูลที่ดึงจากหน่วยความจำหลักไปยังแคชอาจไม่สามารถใช้ได้ก่อนที่จะอ่าน ดังนั้นจึงสร้างปัญหาการมองเห็นในคอร์เดียว   -  person erickson    schedule 29.07.2015
comment
ฉันอยากจะรู้เรื่องนี้เพราะมันจะช่วยให้ฉันเข้าใจวิธีการทำงาน รหัสของฉันจะไม่ขึ้นอยู่กับสิ่งนี้   -  person DPM    schedule 30.07.2015


คำตอบ (2)


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

แต่จะเป็นอย่างไรถ้าเรามี n เธรดและเธรดทั้งหมดทำงานใน cpu core ตัวเดียว (แน่นอนว่าเราไม่สามารถแน่ใจได้ว่าเธรดเหล่านั้นจะทำงานบน 1 คอร์เท่านั้น แต่สมมติว่าเป็นไปได้ที่จะบรรลุเป้าหมายนั้น) ไม่มีทางที่จะ มีการมองเห็นความทรงจำไหม? หรือนี่ไม่ถูกต้อง?

ใช่ การมองเห็น (หน่วยความจำที่ใช้ร่วมกัน) ยังคงมีอยู่หากมี n เธรดที่ทำงานบนคอร์เดียว แต่มีข้อแม้บางประการที่มีอยู่ไม่ว่าจะมีกี่คอร์ก็ตาม โดยหลักแล้วแต่ละเธรดมีหน่วยความจำแคชของตัวเองและตัวแปรอาจมีค่าที่แตกต่างกันในทั้งสองเธรด หากตัวแปรเป็น volatile ค่าของตัวแปรนั้นจะได้รับการอัปเดตในทุกเธรดเสมอ

ฟิลด์อาจถูกประกาศว่ามีความผันผวน ซึ่งในกรณีนี้ Java Memory Model จะตรวจสอบให้แน่ใจว่าเธรดทั้งหมดเห็นค่าที่สอดคล้องกันสำหรับตัวแปร (§17.4)

ฉันขอแนะนำให้คุณอ่านเพิ่มเติมเกี่ยวกับ Java Memory Model

person Jose Martinez    schedule 29.07.2015
comment
จริงๆ แล้ว ฉันไม่ได้คิดว่าทุกเธรดจะมีแคชของตัวเอง ไม่ใช่แค่คอร์ที่แตกต่างกันเท่านั้น ขอบคุณ ! - person DPM; 30.07.2015

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

person ControlAltDel    schedule 29.07.2015
comment
การมองเห็นเป็นคำทั่วไปที่ใช้ในข้อกำหนดภาษา Java และที่อื่นๆ - person erickson; 29.07.2015
comment
และคุณช่วยยกตัวอย่างการอัปเดตบนสแต็กที่มองเห็นได้จากเธรดอื่นได้ไหม มีเพียงตัวแปรภายในเครื่องซึ่งจำกัดอยู่ในสแต็กและฟิลด์ซึ่งอยู่ในฮีป ดังนั้นฉันจึงไม่เข้าใจว่าคุณหมายถึงการอัปเดตอะไร - person erickson; 29.07.2015
comment
การใช้เธรดในระดับต่ำอาจทำให้ตัวแปรบางตัวไม่อยู่ในสแต็กหรือฮีปอย่างเคร่งครัด อาจถูกจัดเก็บไว้ในรีจิสเตอร์ที่มองเห็นได้เฉพาะในเธรดเท่านั้น ประเด็นก็คือคุณไม่รู้จริงๆ และควรถือว่าการทำงานพร้อมกันนั้นจำเป็นต้องมีการซิงโครไนซ์ที่เหมาะสม แทนที่จะตั้งสมมติฐานเกี่ยวกับสภาพแวดล้อมการดำเนินการของคุณ - person Daniel; 29.07.2015
comment
บางอย่างเช่นเฟรมสแต็กดั้งเดิมใช่ไหม นั่นสมเหตุสมผลแล้ว - person erickson; 29.07.2015