Saya mencoba memproses kode di bawah ini menggunakan multithreading di tingkat pesanan.
List<String> orders = Arrays.asList("order1", "order2",
"order3", "order4", "order1");
Eksekusi sekuensial saat ini:
orders.stream().forEach(order -> {
rules.forEach(rule -> {
finalList.add(beanMapper.getBean(rule)
.applyRule(createTemplate.apply(getMetaData.apply(rule), command),
order));
});
});
Saya sudah mencoba menggunakan:
orders.parallelStream().forEach(order -> {}} // code snippet.
Tapi itu mengubah pesanan rules.forEach (rule -> {}} .
Misalnya:
Input:
List<String> orders = Arrays.asList("order1", "order2",
"order3", "order4", "order1");
List<String> rules = Arrays.asList("rule1", "rule2", "rule3");
Output yang diharapkan:
order1 with rule1, rule2, rule3
order2 with rule1, rule2, rule3
Output aktual dengan parallelStream()
:
order1 with rule3, rule1, rule2
order1 with rule2, rule1, rule3
Saya tidak peduli tentang urutan pesanan , tetapi saya peduli tentang aturan pesanan . Pesanan dapat diproses dalam pesanan apa pun, tetapi aturan harus dijalankan dalam urutan yang sama untuk setiap pesanan.
Tolong bantu.
sumber
Anda menambahkan elemen ke
finalList
dari utas yang berbeda secara bersamaan. Hal ini menyebabkan pencampuran hasil penerapan aturan ke pesanan yang berbeda (aturan tidak dikelompokkan berdasarkan pesanan mereka).Anda dapat memperbaikinya dengan membuat daftar sementara untuk masing-masing
order
dan kemudian secara bersamaan menggabungkan semua daftar sementara di afinalList
.Berikut ini cara melakukannya dengan menggunakan Stream-API (Java 9+):
Catatan:
Collectors.flatMapping()
digunakan di sini alih-alih sederhanaflatMap
untuk menjalankan pemetaan datar secara sinkron selama pengumpulan aliran.Analog Java 8:
sumber
beanMapper.getBean(rule) .applyRule(createTemplate.apply(getMetaData.apply(rule), command), order)
bukan fungsi murni, jadi tidak bisa digunakan secara paralel. Cobalah untuk menghilangkan semua efek samping darinya;ConcurrentModificationException
stack trace dapat membantu menemukannya.Akankah ini berhasil?
Keluaran
sumber
Jika itu masalahnya, tidak ada ruang untuk paralelisme yang sebenarnya.
Kapan
dan
hanya menjalankan yang valid untuk 2 pesanan dan 2 aturan,
dan
dianggap tidak valid, itu bukan paralelisme, hanya pengacakan
order
s, mungkin tanpa keuntungan. Jika Anda "bosan" denganorder1
datang pertama kali, Anda dapat mengacak daftar, tetapi hanya itu:Bahkan streaming tidak diperlukan, hanya dua loop bersarang. Uji: https://ideone.com/qI3dqd
Jawaban asli
Tidak. The
order
s mungkin tumpang tindih, tetapi urutanrule
s untuk setiap pesanan disimpan. Mengapa non-paralelforEach
melakukan hal lain?Kode contoh:
Uji: https://ideone.com/95Cybg
Contoh keluaran:
Urutan
order
s dicampur, tetapirule
selalu 1-2-3. Saya pikir output Anda hanya menyembunyikan pasangan (sebenarnya Anda tidak menunjukkan bagaimana itu dihasilkan).Tentu saja dapat diperpanjang dengan beberapa penundaan, jadi pemrosesan
order
s sebenarnya akan tumpang tindih:Uji: https://ideone.com/cSFaqS
Contoh keluaran:
Ini mungkin sesuatu yang Anda lihat, hanya tanpa
orderx
bagian. Denganorder
s yang terlihat, dapat dilacak yangrule
terus menjadi 1-2-3, perorder
. Juga, daftar contoh Anda berisiorder1
dua kali yang pasti tidak membantu dalam melihat apa yang terjadi.sumber
order
s tidak bisa tumpang tindih (apakahrule
itu stateful mungkin, dan ada dalam jumlah terbatas, mungkin hanya satu?). Tetapi secara umum tidak ada paralelisme tanpa hal-hal yang berjalan paralel, itulah inti dari paralelisme.Jika Anda tidak keberatan untuk mencoba perpustakaan pihak ketiga. Berikut adalah contoh dengan perpustakaan saya: sempoa-util
Dan Anda bahkan dapat menentukan nomor utas:
Urutan
rule
akan disimpan.By the way, karena itu dalam aliran paralel, potongan kode
...finalList.add(...
kemungkinan besar tidak akan berfungsi. Saya pikir lebih baik mengumpulkan hasilnya ke daftar:itu juga bisa dilakukan bahkan jika Anda ingin menjaga urutan
order
untuk beberapa alasan nanti:sumber