Poin utama yang belum disebutkan adalah bahwa keadaan suatu objek bisa berubah memungkinkan untuk memiliki identitas objek yang merangkum keadaan itu menjadi abadi.
Banyak program dirancang untuk memodelkan hal-hal dunia nyata yang secara inheren bisa berubah. Misalkan pada pukul 12.51 pagi, beberapa variabel AllTrucks
memegang referensi ke objek # 451, yang merupakan akar dari struktur data yang menunjukkan kargo apa yang terkandung dalam semua truk armada pada saat itu (12:51 pagi), dan beberapa variabel BobsTruck
dapat digunakan untuk mendapatkan referensi ke objek # 24601 menunjuk ke objek yang menunjukkan kargo apa yang terkandung dalam truk Bob pada saat itu (12:51 pagi). Pada pukul 12:52 pagi, beberapa truk (termasuk Bob) dimuat dan dibongkar, dan struktur data diperbarui sehingga AllTrucks
sekarang akan memiliki referensi ke struktur data yang menunjukkan muatan berada di semua truk pada pukul 12:52.
Apa yang harus terjadi BobsTruck
?
Jika properti 'kargo' dari setiap objek truk tidak dapat diubah, maka objek # 24601 akan selamanya mewakili keadaan yang dimiliki truk Bob pada pukul 12:51 pagi. Jika BobsTruck
memegang referensi langsung ke objek # 24601, maka kecuali kode pembaruan yang AllTrucks
juga terjadi untuk memperbarui BobsTruck
, itu akan berhenti mewakili keadaan truk Bob saat ini. Perhatikan lebih lanjut bahwa kecuali BobsTruck
disimpan dalam suatu bentuk objek yang dapat diubah, satu-satunya cara agar pembaruan yang diperbarui AllTrucks
adalah jika kode diprogram secara eksplisit untuk melakukannya.
Jika seseorang ingin dapat menggunakan BobsTruck
untuk mengamati truk Bob negara sambil tetap menjaga semua benda tetap, seseorang bisa BobsTruck
menjadi fungsi abadi yang, mengingat nilai yang AllTrucks
telah atau miliki pada waktu tertentu, akan menghasilkan keadaan truk Bob di waktu itu. Satu bahkan dapat memilikinya memegang sepasang fungsi abadi - salah satunya akan seperti di atas, dan yang lainnya akan menerima referensi ke keadaan armada dan keadaan truk baru, dan mengembalikan referensi ke keadaan armada baru yang cocok dengan yang lama, kecuali bahwa truk Bob akan memiliki negara baru.
Sayangnya, harus menggunakan fungsi seperti itu setiap kali seseorang ingin mengakses keadaan truk Bob bisa menjadi agak menjengkelkan dan rumit. Pendekatan alternatif akan mengatakan bahwa objek # 24601 akan selalu dan selamanya (selama orang memegang referensi untuk itu) mewakili saat keadaan truk Bob. Kode yang ingin berulang kali mengakses kondisi truk Bob saat ini tidak harus menjalankan fungsi yang menghabiskan waktu setiap kali - itu bisa dengan mudah melakukan fungsi pencarian sekali untuk mengetahui bahwa objek # 24601 adalah truk Bob, dan kemudian cukup akses objek itu kapan saja ia ingin melihat kondisi truk Bob saat ini.
Perhatikan bahwa pendekatan fungsional bukan tanpa keuntungan dalam lingkungan single-threaded, atau dalam lingkungan multi-threaded di mana thread sebagian besar hanya akan mengamati data daripada mengubahnya. Setiap pengamat utas yang menyalin referensi objek yang terkandungAllTrucks
dan kemudian memeriksa keadaan truk yang diwakili dengan demikian akan melihat keadaan semua truk pada saat itu meraih referensi. Setiap kali utas pengamat ingin melihat data yang lebih baru, itu hanya dapat mengambil kembali referensi. Di sisi lain, memiliki seluruh keadaan armada yang diwakili oleh satu objek abadi akan menghalangi kemungkinan dua utas memperbarui truk yang berbeda secara bersamaan, karena setiap utas jika dibiarkan pada perangkatnya sendiri akan menghasilkan objek "armada negara" baru yang termasuk kondisi baru truknya dan kondisi lama lainnya. Kebenaran dapat dipastikan jika masing-masing utas menggunakan CompareExchange
untuk memperbarui AllTrucks
hanya jika itu tidak berubah, dan menanggapi gagalCompareExchange
dengan meregenerasi objek keadaannya dan mencoba kembali operasi, tetapi jika lebih dari satu utas mencoba operasi penulisan simultan, kinerja umumnya akan lebih buruk daripada jika semua penulisan dilakukan pada satu utas; semakin banyak utas mencoba operasi simultan tersebut, semakin buruk kinerjanya.
Jika objek truk individu dapat berubah tetapi memiliki identitas yang tidak dapat diubah , skenario multi-ulir menjadi lebih bersih. Hanya satu utas yang diizinkan beroperasi pada suatu waktu pada truk tertentu, tetapi utas yang beroperasi pada truk yang berbeda dapat melakukannya tanpa gangguan. Meskipun ada beberapa cara seseorang dapat meniru perilaku seperti itu bahkan ketika menggunakan objek yang tidak dapat diubah (misalnya seseorang dapat mendefinisikan objek "AllTrucks" sehingga pengaturan keadaan truk milik XXX ke SSS hanya akan memerlukan menghasilkan objek yang mengatakan "Pada [Waktu], keadaan truk milik [XXX] sekarang [SSS]; keadaan segalanya adalah [Nilai lama AllTrucks] ". Menghasilkan objek seperti itu akan cukup cepat sehingga bahkan di hadapan pertengkaran, sebuahCompareExchange
loop tidak akan lama. Di sisi lain, menggunakan struktur data seperti itu akan secara substansial meningkatkan jumlah waktu yang dibutuhkan untuk menemukan truk orang tertentu. Menggunakan objek yang bisa berubah dengan identitas yang tidak berubah menghindari masalah itu.