thắc mắc Concurrency, Parallel, Asynchronous, Multithreading khác nhau như thế nào?

tại sao khi fetch data bác lại xài 2 thằng này v ạ, bác cho e hỏi ít ưu nhược điểm được không. ví dụ có 2 request 1 get 1 update, thì phần này handle ntn hay cần config phía DB ko nhỉ ?
Tech stack mình dùng ở đây là Java, Spring(Boot), Hibernate, JPA + Oracle.

Bình thường thì fetch data từ database không cần thread mới. Nhưng bên mình có mấy trường hợp đặc biệt mới phải làm vậy. Bạn nào dùng Spring + JPA chắc biết JPA level 1 cache (Persistent Context) được dùng để check xem data có thay đổi không trước khi JPA query trực tiếp vào database. Nếu bình thường query 2 lần liên tiếp cùng 1 query thì chỉ lần 1 JPA query vào database, còn lần 2 thì không, data sẽ được trả thẳng từ cache nếu JPA nhận thấy không có gì thay đổi. Bên mình có 1 table được update bởi 2 service khác nhau. Service A query > Service B update > Service A query tiếp thì ko nhận được update mới. Phải dùng riêng 1 thread khác để fetch data rồi lấy bằng Callable.get() thì được.

Còn REST call, ví dụ nếu bạn muốn gọi 1 loạt 3, 4 REST call rồi collect kết quả thì chạy tất cả REST call trong các Thread khác để đỡ mất thời gian chờ.

Request get với update của bạn nếu là từ database (SQL) thì hầu hết gọi query SELECT/UPDATE bình thường trong thread hiện tại thôi, không phải tạo thread riêng. Đặc biệt lắm mới tạo thread riêng.
Còn nếu là noSQL thì mình chưa dùng nên không đoán bừa :v
 
Bác dịch từ quyển nào thế? cho xin link tham khảo với :)
Chỉ với một Judit Polgar, người chỉ có hai tay và chỉ thực hiện một nước đi mỗi lần. Nhưng bằng cách chơi không đồng bộ đã giúp giảm thời gian của cuộc đấu xuống từ 12 giờ còn 1 giờ. Vì vậy, cooperative multitasking (hợp tác đa nhiệm) là một cách nói fancy ý chỉ về event loop (vòng lặp sự kiện) của chương trình (điều này sẽ nói sau) thực hiện giao tiếp với nhiều task cho phép từng task thay phiên nhau chạy vào những thời điểm rảnh rỗi của CPU.

mình có thắc mắc ở chỗ này AsyncIO khác gì multithread nhỉ, vì nếu giải thích như trên thì cả 2 đều chạy trên core của CPU (số lượng có hạn) và nó luôn tận dụng tối đa thời gian rảnh.

Sent from Xiaomi Redmi Note 9S using vozFApp
 
Last edited:
Bác dịch từ quyển nào thế? cho xin link tham khảo với :)


mình có thắc mắc ở chỗ này AsyncIO khác gì multithread nhỉ, vì cả 2 đều chạy trên core của CPU (số lượng có hạn) và nó luôn tận dụng tối đa thời gian rảnh.

AsyncIO nó khác lắm.

Câu cùng chạy trên CPU chưa chắc đúng.

Multi-threading thì công việc chạy trên thread khác và sẽ được chạy trên core (CPU nào đó) được cấp phát.

Chỗ AsyncIO thì khác. Ví dụ khi call ra ngoài để lấy kết quả. Sau khi push hết các packet lên network device rồi, thì sau đó sẽ là bước chờ kết quả. Thực tế lúc chờ chả mất CPU gì cả nên chỗ này có một cách khác: Khi có gói tin trả về đến, network device có thể tự buffer một số thông tin sau đó mới báo ngắt lên OS, sau có thể trigger việc có gói tin cho app ghi nhận/xử lý. Còn CPU đến lúc call xong việc đẩy gói tin ra network thì đi làm việc khác.

Bước đẩy ra network device thực ra cũng nhanh, bản chất là đẩy vào buffer của network device thôi nên nó cũng không tốn CPU.

Có những phương pháp advanced hơn (DMA) thì còn ko tốn CPU mà tốn processor khác.
 
Bác dịch từ quyển nào thế? cho xin link tham khảo với :)


mình có thắc mắc ở chỗ này AsyncIO khác gì multithread nhỉ, vì cả 2 đều chạy trên core của CPU (số lượng có hạn) và nó luôn tận dụng tối đa thời gian rảnh.

Vì chi phí context-switch của thread là rất lớn (so với một vòng lặp đơn giản). Với multithread thì sau khi yêu cầu thực hiện thao tác I/O thì có những việc sau cần phải thực hiện:
  • Backup hết tất cả các thanh ghi vào RAM, VD x86 thì bao gồm 16 thanh ghi integer, 16 thanh ghi SIMD, các thanh ghi floating point, các thanh ghi hệ thống mà user không tác động được,
  • Flush CPU cache (cache level nào thì tùy vào OS và kiến trúc),
  • Chuyển trạng thái của thread sang WAITING
  • OS scheduler kiếm một thread ready khác để thực thi (nếu có).

Đến khi I/O thực hiện xong, tức là device (VD disk, NIC) đã interrupt cho OS thì OS đổi thread đó sang trạng thái READY, nhưng điều đó không có nghĩa là nó sẽ được tiếp tục run mà còn phải chờ thread khác nữa. Khi có slot thì làm ngược lại những điều trên.

So với việc async bằng event-loop trên 1 thread thì:
  • Chỉ phải backup những thanh ghi mà coroutine đang dùng,
  • Không cần flush cache,
  • Để event-loop xác định xem coroutine nào chạy tiếp theo thì đơn giản hơn là OS scheduler xác định thread nào chạy tiếp.
 
Toy hiểu đơn giản như này.
Lấy ví dụ là nấu cơm, canh đi. Với 1 người làm tương đương CPU 1 core 1 process.
Concurrent:
- Nấu cơm -> Đợi Cơm chín -> Nấu Canh -> Đợi canh chín => Xong
Parallel:
- Nấu cơm -> Nấu Canh -> Đợi cơm chín -> Đợi canh chín => Xong
Sai rồi. Ví dụ concurrency của bạn nó là xử lý đồng bộ, còn ví dụ parallel kia mới là concurrency.
 
uy tin' nhe'
 

Attachments

  • Screenshot 2023-03-10 140213.png
    Screenshot 2023-03-10 140213.png
    316.3 KB · Views: 67
  • Screenshot 2023-03-10 140245.png
    Screenshot 2023-03-10 140245.png
    302.1 KB · Views: 75
AsyncIO nó khác lắm.

Câu cùng chạy trên CPU chưa chắc đúng.

Multi-threading thì công việc chạy trên thread khác và sẽ được chạy trên core (CPU nào đó) được cấp phát.

Chỗ AsyncIO thì khác. Ví dụ khi call ra ngoài để lấy kết quả. Sau khi push hết các packet lên network device rồi, thì sau đó sẽ là bước chờ kết quả. Thực tế lúc chờ chả mất CPU gì cả nên chỗ này có một cách khác: Khi có gói tin trả về đến, network device có thể tự buffer một số thông tin sau đó mới báo ngắt lên OS, sau có thể trigger việc có gói tin cho app ghi nhận/xử lý. Còn CPU đến lúc call xong việc đẩy gói tin ra network thì đi làm việc khác.

Bước đẩy ra network device thực ra cũng nhanh, bản chất là đẩy vào buffer của network device thôi nên nó cũng không tốn CPU.

Có những phương pháp advanced hơn (DMA) thì còn ko tốn CPU mà tốn processor khác.
giải thích như bác chuẩn hơn này, chứ thấy bác kia dịch từ sách qua chưa rõ lắm.
 
Em có thể giải thích cho bác về Async như sau

Cái nhìn tổng quát về Async IO​

Async IO ít được biết đến hơn so với những thuật ngữ quen thuộc của lập trình cổ điển mà ta đã từng học, thực hành và kiểm nghiệm (multiprocessing threading). Phần này sẽ cung cấp cho bạn bức tranh đầy đủ hơn về async IO (lập trình bất đồng bộ) là gì và cách chúng được sử dụng cho các trường hợp cụ thể.

Async IO được dùng ở đâu​

Tính đồng thời (concurrency) và tính song song (parallelism) là những topic mở rộng không dễ để tìm hiểu. Mặc dù bài viết này tập trung vào async IO và cách triển khai nó trong Python, nhưng bạn cũng nên dành một phút để so sánh async IO với các “cộng sự của nó” để có được cái nhìn bao quát về cách dùng nó phù hợp trong những bài toán lớn.

parallelism bao gồm việc thực hiện nhiều hành động trong cùng một lúc. Multiprocessing được hiểu là việc thực hiện các tác vụ song song và nó đòi hỏi phải chia sẻ các tác vụ đó cho các đơn vị xử lý trung tâm (cores). Multiprocessing rất phù hợp cho các tác vụ liên quan đến CPU: Như việc thực hiện for-loop hàng loạt và các phép tính toán học thường thuộc loại này.

concurrency là một thuật ngữ mở rộng của parallelism. Bạn có thể hiểu nó theo nghĩa là một tác vụ có thể chạy thay nhau cùng lúc (cái này chạy một chút rồi đến cái kia chạy một chút - thuật ngữ này gọi là overlapping manner). Và lưu ý rằng đồng thời (concurrency) không có nghĩa là song song (parallelism).

Threading là một mô hình thực thi concurrency mà ở đó nhiều luồng thay phiên nhau thực thi các tác vụ. Một process có thể chứa nhiều thread. Python thực hiện một complicated relationship với threading thông qua GIL, nhưng ta sẽ không nói tới trong bài viết này.

Điều quan trọng cần biết về threading là nó sẽ tốt hơn cho các tác vụ có IO. Trong khi các tác vụ CPU được đặc trưng bởi các core máy tính làm việc liên tục từ đầu đến cuối, thì các tác vụ có liên quan tới IO lại bị chi phối rất nhiều vào thời gian đợi input/output để hoàn thành.

Tóm cái váy lại, concurrency bao gồm cả multiprocessing (tốt cho các tác vụ cần CPU) và threading (cho các tác vụ có IO). Multiprocessing là một dạng parallelism mà ở đó parallelism là tập con của concurrency. Thư viện chuẩn của Python có cung cấp các package multiprocessing, threading và concurrent.futures để hỗ trợ cả hai thứ trên.

Giờ đã đến lúc đưa một thành viên mới vào danh sách này. Trong vài năm qua một thiết kế riêng biệt đã được tích hợp toàn diện hơn vào CPython: asynchronous IO, có thể được gọi thông qua package asyncio trong bộ thư viện chuẩn và các keyword async và await. Để rõ ràng, async IO không phải là một khái niệm mới được phát minh và nó đã tồn tại hoặc đang được tích hợp vào các ngôn ngữ và runtime environment như Go, C#, Scala.

asyncio package được Python documentation ví như là một thư viện để viết code concurrent. Tuy nhiên, async IO không phải là threading, cũng không phải là multiprocessing. Nó không được xây dựng dựa trên hai thứ này.

Thực tế, async IO là một thiết kế single-threaded, single-process: nó sử dụng cooperative multitasking (hợp tác đa nhiệm), một thuật ngữ mà bạn sẽ hiểu rõ khi đọc xong bài này. Nói cách khác async IO mang lại cảm giác như là concurrency (chạy đồng thời) mặc dù sử dụng single-thread trong một single process. Coroutines (một tính năng trung tâm của async IO) có thể được lên lịch đồng thời, nhưng chúng vốn dĩ không đồng thời.

Nhắc lại lần nữa, async IO là một kiểu lập trình concurrent, nhưng nó không phải là parallelism. Nó giống threading hơn là multiprocessing nhưng rất khác biệt so với cả hai thứ này và là một công cụ độc lập trong các công cụ lập trình lập trình concurrency.

Và một thuật ngữ nữa xuất hiện. Nó có nghĩa là gì khi một thứ gì đó bất đồng bộ (asynchronous)? Đây không phải là một định nghĩa cụ thể. Nhưng với mục đích của bài viết này, ta có thể hiểu nó với hai thuộc tính sau:
  • Các tiến trình bất đồng bộ có thể “tạm dừng” trong khi chờ đợi kết quả cuối cùng của chúng và để các tiến trình khác chạy trong lúc nó chờ.
  • Code bất đồng bộ thông qua cơ chế trên tạo ra một hiệu ứng thực thi đồng thời. Nói cách khác, code bất đồng bộ cho ta cảm giác như nó đang concurrency.

Dưới đây là sơ đồ tổng quát. Các thuật ngữ màu trắng đại diện cho các khái niệm và các thuật ngữ màu xanh lá cây biểu thị các cách thức mà chúng được triển khai hoặc thực hiện:
Concurrency versus parallelism

Ta sẽ dừng lại ở việc so sánh giữa các mô hình lập trình đồng thời. Bài viết này tập trung vào thành phần con của async IO, cách sử dụng chúng và những API có trong nó. Để tìm hiểu thêm về sự khác biệt giữa threading, multiprocessing và async IO, hãy dừng lại ở đây và xem bài viết tổng quan về concurrency trong Python của Jim Anderson.

Giải thích về Async IO​

Async IO thoạt đầu nghe có vẻ vô lý. Làm thế nào mà một thứ gì đó có thể giúp code chạy đồng thời mà chỉ sử dụng một thread và một CPU core? Tôi (tác giả) chưa bao giờ là người giỏi ra ví dụ, vì thế tôi muốn cho các bạn xem một câu từ bài nói chuyện của Miguel Grinberg tại PyCon năm 2017, giải thích mọi thứ khá hay như sau:

Vua cờ Judit Polgár tổ chức một cuộc triển lãm cờ vua trong đó cô ấy chơi với nhiều kỳ thủ nghiệp dư. Cô ấy có hai cách tiến hành: đồng bộ và không đồng bộ.

Giả sử:
  • 24 đối thủ
  • Judit thực hiện 1 nước cờ trong 5 giây
  • Đối thủ thì mất 55 giây để thực hiện một bước
  • Một ván trung bình có 30 nước di chuyển đôi (tổng cộng là 60 lần qua lại giữa hai người)

Giải pháp đồng bộ: Judit chơi một ván mỗi lần, không bao giờ chơi hai ván cùng lúc, cho đến khi xong. Mỗi ván mất (55+5) * 30 == 1800 giây, hay 30 phút. Suy ra chơi với toàn bộ 24 người sẽ mất 24 * 30 == 720 phút, hay 12 giờ.

Giải pháp không đồng bộ: Judit chơi từ bàn này sang bàn khác, thực hiện một lần di chuyển trên từng bàn cờ. Nhân lúc đối thủ suy nghĩ để thực hiện bước đi kế tiếp thì trong thời gian đợi đó cô ấy đi qua bàn khác để đi nước tiếp theo. Để thực hiện một lần đi cờ trên cả 24 bàn Judit mất 24 * 5 == 120 giây, hay 2 phút. Suy ra toàn bộ ván cờ cho tất cả 24 bàn cờ sẽ mất 3600 giây, hay 1 giờ.

Chỉ với một Judit Polgar, người chỉ có hai tay và chỉ thực hiện một nước đi mỗi lần. Nhưng bằng cách chơi không đồng bộ đã giúp giảm thời gian của cuộc đấu xuống từ 12 giờ còn 1 giờ. Vì vậy, cooperative multitasking (hợp tác đa nhiệm) là một cách nói fancy ý chỉ về event loop (vòng lặp sự kiện) của chương trình (điều này sẽ nói sau) thực hiện giao tiếp với nhiều task cho phép từng task thay phiên nhau chạy vào những thời điểm rảnh rỗi của CPU.

Trong Async IO, khi một function bị block thì async IO sẽ cho các chương trình khác chạy trong thời gian block đó (một function block những function khác từ khi nó bắt đầu đến khi nó return kết quả - thời gian block đó thường được biết đến với thuật ngữ Độ phức tạp thuật toán).

Trên là trích từ bài dịch của mình khi còn học đại học về Async IO trong Python. Bị Viblo cướp trắng trợn nên cũng hết muốn dịch mà toàn giữ riêng cho mình. Sau khi đi làm được gần 1 năm, bị kêu đi nghĩa vụ nên nghỉ việc dọn về, về thì biết tin dự bị nên quay lại Đà Nẵng :) Đang thất nghiệp, sẵn tiện ôn bài để đi phỏng vấn thì gặp post của bác. Mong giúp ích.
Fenca đang ở Đà Nẵng à, có việc chưa fence?
 
Ví dụ quầy bán nước của The Coffee House, mỗi khách hàng là một task/ job cần được xử lý mà nhân viên quầy (thread) là người chịu trách nhiệm xử lí.

Async: Nhân viên nhập order xong, đưa request của khách hàng vào queue, sau đó đưa một cái thẻ cho khách, khách đi làm chuyện gì khác tùy khách, bao giờ có nước tụi tui thông báo.

Sync: Khách order nước xong, nhân viên làm nước rồi trả cho khách, khách này đi thì mới tiếp khách khác.

Concurrency: Vừa tính tiền cho khách, vừa làm nước, vừa lau bàn, bưng bê nhưng mỗi task một lần thôi, task này đang làm thì không làm task khác nữa.

Parallel: Ví dụ khách A trả tiền bằng một xấp 100 đồng, nhân viên đếm sấp mặt không nổi, gọi thêm thằng khác đếm phụ -> parallel.

Không biết em hiểu thế này có đúng không nhỉ, mong các cao nhân chỉ bảo.
 
Last edited:
T không quan tâm nếu ai hỏi Async, hay Parallel hay Concurrrent. Cái quan trọng duy nhất cần biết là:

  • Tất cả mọi thứ là threads (a process has at least 1 thread, cái này không quan trọng trong case này).
  • Một function được gọi là thread safe thì không có race condition, cách dễ nhất để nó thread-safe là acquire lock khi bước vào function và release khi out function. (ở C thì cần acquire/release thủ công, C++ có lock_guard/scope_lock nó tự release khi out function dùm luôn kể cả có exception, Java thì ... Nói chung là ý tưởng tương tự).
Exp:
Code:
class A {
    mutex lock; // mutex == lock type
    int age = 0;
    string name = "Mẫn Nhi";

    // Cách C acquire lock
    public void set_name(string new_name) {
        // acquire lock khi bước vào function
        lock.acquire();
        name = new_name;
        lock.release(); // Cách C release lock
    }

    // Cách C++ acquire lock
    public void set_age(int new_age) {
        // acquire lock khi bước vào function
        lock_guard<mutex> l(lock);
        age = new_age;
        // C++ tự release lock khi bước ra khỏi function này, đỡ mất công lock.release()
    }
    ... vân vân và mây mây
}

- Cách trên thì mọi thứ work rất là tốt luôn, chả vấn đề gì luôn, với m thì m sẽ luôn làm như thế, trừ phi bi hỏi căng thì ... đáp kiểu khác z ... :).

- Bạn muốn nó perform tốt hơn thì dùng Reader-Writer lock, case này thì multiple readers có thể chạy paralell luôn. Hoặc chia global,local locks.

- Mỗi lần một thread nào đấy nó acquire lock mà lock không khả dụng, thì thread này sẽ được sleep.
+ thread được mô tả bằng một struct thread (hoặc một class thread cho dễ hiểu) gồm mấy fields như: Program counter, stack pointer, set of used registes, thread name ...v.v.
+ mỗi lock sẽ có một cái list of threads.

sleep nghĩa là cái struct thread này sẽ chuyển status thành THREAD_BLOCKED và sẽ được thảy vào cái list of threads của cái lock nó đang acquire. Blocked thì OS không schedule để chạy.

  • Khi nào nó được schedule lại? khi mà cái thread (holder of the lock) gọi lock.release() thì, lúc này OS sẽ loop qua cái List<thread> của cái lock và put cái thread này lại vào cái ready_list của OS, đổi status thành THREAD_READY. Lúc này thread đã sẵn sàng để được schedule để run. Khi thread được OS run (struct thread nằm trên CPU r đó) lúc này lock có thể available hoặc không.
  • Available thì thread sẽ run, và run thì nó sẽ chạy ngay cái dòng ở duới chỗ lock.acquire() trước đó, cho nên cái thread này lúc này sẽ là lock holder, và continue to run cái critical section của nó thoai.
  • Không available thì thread lại bị put to sleep tiếp.

Hi vọng mấy điểm này nó giúp các bạn trong việc mần món synchronization này nghe. Yoo.
 
Last edited:
Async thường nó chạy single thread đó thím, các ngôn ngữ khác có implement chạy đa luồng hay k thì mình k rõ thím nào rành giải thích thêm với
Bác dịch từ quyển nào thế? cho xin link tham khảo với :)


mình có thắc mắc ở chỗ này AsyncIO khác gì multithread nhỉ, vì cả 2 đều chạy trên core của CPU (số lượng có hạn) và nó luôn tận dụng tối đa thời gian rảnh.
 
Async thường nó chạy single thread đó thím, các ngôn ngữ khác có implement chạy đa luồng hay k thì mình k rõ thím nào rành giải thích thêm với
Chỗ này đừng bias fen. Thường anh em bập ngay vào Nodejs hay cho rằng kiểu này nhưng thực ra nó phụ thuộc vào runtime engine.
Như bên Java thì nhiều engine nó chơi cả combo async + multithread + multiprocess để khai thác tối đa multiple CPU, multiple CPU-core luôn.
Btw đang hóng Java Fiber nó ổn áp qua test chơi, lâu rồi ko đụng Java thấy bây giờ nhiều tính năng quá chạy theo ko kịp luôn.
 
Chỗ này đừng bias fen. Thường anh em bập ngay vào Nodejs hay cho rằng kiểu này nhưng thực ra nó phụ thuộc vào runtime engine.
Như bên Java thì nhiều engine nó chơi cả combo async + multithread + multiprocess để khai thác tối đa multiple CPU, multiple CPU-core luôn.
Btw đang hóng Java Fiber nó ổn áp qua test chơi, lâu rồi ko đụng Java thấy bây giờ nhiều tính năng quá chạy theo ko kịp luôn.

Thực ra cái runtime của nodejs (viết bằng C++) cũng có trường hợp dùng đa luồng, cái nào dùng đc async api của os thì dùng thôi.

Sent from Xiaomi Redmi Note 9S using vozFApp
 
Ví dụ quầy bán nước của The Coffee House, mỗi khách hàng là một task/ job cần được xử lý mà nhân viên quầy (thread) là người chịu trách nhiệm xử lí.

Async: Nhân viên nhập order xong, đưa request của khách hàng vào queue, sau đó đưa một cái thẻ cho khách, khách đi làm chuyện gì khác tùy khách, bao giờ có nước tụi tui thông báo.

Sync: Khách order nước xong, nhân viên làm nước rồi trả cho khách, khách này đi thì mới tiếp khách khác.

Concurrency: Vừa tính tiền cho khách, vừa làm nước, vừa lau bàn, bưng bê nhưng mỗi task một lần thôi, task này đang làm thì không làm task khác nữa.

Parallel: Ví dụ khách A trả tiền bằng một xấp 100 đồng, nhân viên đếm sấp mặt không nổi, gọi thêm thằng khác đếm phụ -> parallel.

Không biết em hiểu thế này có đúng không nhỉ, mong các cao nhân chỉ bảo.
ví dụ concurrency của fen có vẻ chưa đúng , tôi đã debug và thấy rằng mỗi task khi submit lên executorservice thì sẽ chạy bởi 1 thread khác nhau - tức là có thể thực hiện các task song song với nhau

via theNEXTvoz for iPhone
 
còn parallel bản chất là sẽ thực hiện 1 task lớn bằng cách chia nhỏ thành các subtask . Nếu sử dụng parallel mà ko xem kĩ usecase thì có thể sẽ rơi vào trường hợp race condition .

via theNEXTvoz for iPhone
 
Bình thường thì fetch data từ database không cần thread mới. Nhưng bên mình có mấy trường hợp đặc biệt mới phải làm vậy. Bạn nào dùng Spring + JPA chắc biết JPA level 1 cache (Persistent Context) được dùng để check xem data có thay đổi không trước khi JPA query trực tiếp vào database. Nếu bình thường query 2 lần liên tiếp cùng 1 query thì chỉ lần 1 JPA query vào database, còn lần 2 thì không, data sẽ được trả thẳng từ cache nếu JPA nhận thấy không có gì thay đổi. Bên mình có 1 table được update bởi 2 service khác nhau. Service A query > Service B update > Service A query tiếp thì ko nhận được update mới. Phải dùng riêng 1 thread khác để fetch data rồi lấy bằng Callable.get() thì được.
Cho mình hỏi chút chỗ này nhé.
Mình đồng ý với bạn việc query JPA sẽ lấy từ first level cache.
Nhưng có vẻ giải pháp sử dụng 1 thread khác để query để nhận được state mới của entity thì mình thấy chưa hợp lí lắm.
Về lí thuyết thì có thể dùng entity manager để thực hiện refresh lại trạng thái mới nhất của entity đó là được mà nhỉ. Hoặc chỉ cần đi sang một session khác là được ?
Có lẽ có lí do khác khi bạn sử dụng thread chứ không chỉ là cần state mới của entity.
 
Cho mình hỏi chút chỗ này nhé.
Mình đồng ý với bạn việc query JPA sẽ lấy từ first level cache.
Nhưng có vẻ giải pháp sử dụng 1 thread khác để query để nhận được state mới của entity thì mình thấy chưa hợp lí lắm.
Về lí thuyết thì có thể dùng entity manager để thực hiện refresh lại trạng thái mới nhất của entity đó là được mà nhỉ. Hoặc chỉ cần đi sang một session khác là được ?
Có lẽ có lí do khác khi bạn sử dụng thread chứ không chỉ là cần state mới của entity.
À có vẻ hay. Nhưng trường hợp của mình là cần tìm tất cả các data đã được update bởi 1 service khác, không phải 1 entity cụ thể nên refresh entity không giúp được :cautious:.
 
Hiện tại thì sài bất đồng bộ là tốt nhất, ko tốn nhiều thread, dễ lập trình, tốn ít bộ nhớ, hiệu quả ổn.
Sài threading khi ông không hiểu rõ về nó, rất dễ dính bug đa luồng, tốt nhất là sài các thread riêng biệt nhau ko nên share 1 biến chung bất kì nào cả, nhưng mọi thứ ông lập trình, đều phải đi qua hệ điều hành, nên nói về nhanh cũng chưa phải là nhanh nhất, có còn liên quan tới hệ điều hành, cấu hình phần cứng, ngôn ngữ lập trình.
Lập trình đa luồng thực sự, tận dụng toàn bộ cpu thì ông chỉ có lập trình nhúng, nơi viết code trên chính con chip chứ ko thông qua hệ điều hành.
Tóm lại nên sài bất đồng bộ, ngôn ngữ nào cũng hỗ trợ sẵn, chả cần phải tìm hiểu gì nhiều
 
Back
Top