Hello,
I have a multi-threading Java application (like a web server). ABCL is already added to it but is not used too much. I have a particular need within that application that I think ABCL would be well suited for, but I first need to better understand how ABCL functions in a multithreading environment. What I need is as follows.
I have some Lisp code and data that will be defined both by .lisp files and from within Java. This code and data will be used by a multi-threading Java application in a read-only way. However, the Java threads themselves need to be able to introduce Lisp data that must be unique to each thread and gets deleted when the thread ends (presumably by the GC).
Is there a way to do this with ABCL?
Thank you!
Blake McBride
Yes, ABCL threads are Java threads underneath.
Store the per-thread data in a java.lang.ThreadLocal variable, then it will be garbage collected when the thread ends. (If Thread A may want to access Thread B's per-thread data, then that'll need more thought.)
The bordeaux-threads library's MAKE-LOCK creates a Java ReentrantLock. Follow the usual rules for portably and correctly accessing data from multiple threads. https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html
Vibhu
Thanks Vibhu! However, although related, I don't see how your answer answered my question. (Or, perhaps it does but I don't get it.)
I'm not really asking about how Java threads work or the fact that all Java programs (including ABCL) work with threads (although they may not be thread-safe). I already understand that.
I'm asking:
A. If I can accomplish what I desire using the regular Java and ABCL APIs.
B. How?
Thanks!
Blake
On Thu, Sep 19, 2024 at 8:04 AM Vibhu Mohindra vibhu.mohindra@gmail.com wrote:
Yes, ABCL threads are Java threads underneath.
Store the per-thread data in a java.lang.ThreadLocal variable, then it will be garbage collected when the thread ends. (If Thread A may want to access Thread B's per-thread data, then that'll need more thought.)
The bordeaux-threads library's MAKE-LOCK creates a Java ReentrantLock. Follow the usual rules for portably and correctly accessing data from multiple threads. https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html
Vibhu
On 19/09/2024 16:48, Blake McBride wrote:
Thanks Vibhu! However, although related, I don't see how your answer answered my question. (Or, perhaps it does but I don't get it.)
Oh sorry. I tried writing some code, then realised there'd be too many variations that all met your description, so decided to deliver pieces instead that would help you build what you wanted.
I'm not really asking about how Java threads work or the fact that all Java programs (including ABCL) work with threads (although they may not be thread-safe). I already understand that.
I'm asking:
A. If I can accomplish what I desire using the regular Java and ABCL APIs.
I believe so. In my reading of ABCL's code, I've always regarded it as having been designed for multi-threaded access and have encountered nothing that told me otherwise, (except for a couple of things, irrelevant here, that were minor bugs and may have been fixed (interpreter initialisation; debugger garbling sterr) but I may be misremembering.) I'd be surprised if ABCL's designer said ABCL wasn't meant to be used by multiple threads.
B. How?
I wasn't been able to write an example because I couldn't tell which part you were uncertain about. I'll list some pieces again, in the hope that they'll help. (If they don't, I'll try again.)
Regarding your data defined in Java and Lisp, let's call these: class Data { static int x = 10; } (defvar *y* 10) I'll choose to protect them here with a single lock, defined in Java: class L { static final ReentrantLock lck = new ReentrantLock(); }
Now in every Java and Lisp function that accesses either Data.x or *y*, acquire/release the lock around the actual work: Java: void f() { L.lck.lock(); try { ... } finally { L.lck.unlock(); } } Lisp: ;initialise (use-package "JAVA") (defparameter *lck* (jfield (jclass "L") "lck")) ;and in application functions in the rest of the program ... (defun g () (jcall "lock" *lck*) (unwind-protect (work-with-data) ;or whatever (jcall "unlock" *lck*))) Defining a macro for this pattern will help.
Regarding some data being read-only, fine, but the above doesn't require that, so is more general.
Regarding thread-unique data, define the ThreadLocal in Java, then get/set it from Java/Lisp as needed as you would any other Java variable from Java/Lisp. JFIELD as shown above happens to also be setf-able.
On 19/09/2024 20:01, Blake McBride wrote:
With regard to my question, I'd like to add that the difficulty is that I do not know what ABCL is doing internally. Is it thread safe? Is it always thread safe?
To the extent that a language can be thread-safe (as opposed to a function, data-structure, or abstract data-type), I believe that yes, ABCL is thread-safe in the same sense that Java is.
Vibhu
Worth looking at Clojure too. It handles multi threading quite well.
On Thu, Sep 19, 2024 at 4:38 AM Blake McBride blake@mcbride.name wrote:
Hello,
I have a multi-threading Java application (like a web server). ABCL is already added to it but is not used too much. I have a particular need within that application that I think ABCL would be well suited for, but I first need to better understand how ABCL functions in a multithreading environment. What I need is as follows.
I have some Lisp code and data that will be defined both by .lisp files and from within Java. This code and data will be used by a multi-threading Java application in a read-only way. However, the Java threads themselves need to be able to introduce Lisp data that must be unique to each thread and gets deleted when the thread ends (presumably by the GC).
Is there a way to do this with ABCL?
Thank you!
Blake McBride
Not a fan of Clojure, but thanks!
With regard to my question, I'd like to add that the difficulty is that I do not know what ABCL is doing internally. Is it thread safe? Is it always thread safe?
Thanks!
Blake
On Thu, Sep 19, 2024 at 12:42 PM Garrett P Dangerfield < garrett@dangerimp.com> wrote:
Worth looking at Clojure too. It handles multi threading quite well.
On Thu, Sep 19, 2024 at 4:38 AM Blake McBride blake@mcbride.name wrote:
Hello,
I have a multi-threading Java application (like a web server). ABCL is already added to it but is not used too much. I have a particular need within that application that I think ABCL would be well suited for, but I first need to better understand how ABCL functions in a multithreading environment. What I need is as follows.
I have some Lisp code and data that will be defined both by .lisp files and from within Java. This code and data will be used by a multi-threading Java application in a read-only way. However, the Java threads themselves need to be able to introduce Lisp data that must be unique to each thread and gets deleted when the thread ends (presumably by the GC).
Is there a way to do this with ABCL?
Thank you!
Blake McBride
armedbear-devel@common-lisp.net