PDA

View Full Version : TechTip: Running RPG Programs in Multi-Threaded Jobs



Guest.Visitor
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
I have a few thoughts / questions... 1. I think one of the points (#1) should be made clearer: Code Thread(*Serialize) in every module that could be in the call stack in a multi-threaded job. IE: If the call stack is 10 deep, all 10 need this H-spec. 2. Why wouldn't you just code Thread(*Serialize) in every single module then? 3. Are OPM CL programs already thread safe? CLLE programs? 4. Does coding Thread(*Serialize) still create just object? I swear I read a while back that this creates 2 objects, 1 hidden. Chris

Guest.Visitor
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Chris, I learned about this a few years back so my memory may be spotty. A company I was working at had me write some procedures that were going to be called by web applications. I think the web apps were written in Java but I'm not so sure. I haven't worked with threads since. My understanding is that: 1. If you know the modules will run in multithreaded jobs, all modules called in the job must use Thread(*Serialize). 2. Yes. Code all modules that will run in multithreaded jobs that way. 3. No OPM program is threadsafe. I don't know about CLLE. 4. I remember hearing or reading the same thing. the second object somehow enforces the serialization. I also understand that RPG programs, both OPM and ILE do not spawn multithreaded jobs. As a general rule, I'd stay away from running any RPG procedure in multithreaded jobs. This is a quote from the ILE RPG manual, Ch 13: Control Specifcations: "Normally, running an application in multiple threads can improve the performance of the application. In the case of ILE RPG, this is not true in general. In fact, the performance of a multithreaded application could be worse than that of a single-thread version when the thread-safety is achieved by serialization of the procedures at the module level. Running ILE RPG procedures in a multithreaded environment is only recommended when required by other aspects of the application (for example, when writing a Domino exit program or when calling a short-running RPG procedure from Java). For long-running RPG programs called from Java, we recommend using a separate process for the RPG program." Tom.

Guest.Visitor
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
1. If you know the modules will run in multithreaded jobs, all modules called in the job must use Thread(*Serialize). Tom, someone can't predict if a module written today might get called from a Java program coded a year from now (or anywhere in the call stack of that call). And if the Java programmer doesn't know RPG, they sure won't think twice about just calling the RPG program that doesn't use Thread(*Serialize). And if someone does realize that existing RPG modules might need to now use need to Thread(*Serialize), how do they determine which ones? Through lots of research? (Hawkeye/Abstract/PDM scans/etc) That's why I say why not just code it in EVERY RPG module? And you're correct, RPG is not a multi-threaded language. That's why having RPG and Java communicate via data queues is a nice clean hand-off. Thanks for the info. Chris

Guest.Visitor
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
You're welcome Chris. About an RPG program someday being used in a multithreaded job... I think you have to pretty much trust that the developers at the time will do enough research to realize that calling RPG from Java may have ramifications. The java folks won't know what programs to call anyway without research as you suggested using tools, unless they've also done RPG. You can't predict anything. I'm in a situation now where I'm changing code I wrote in 1987. It's still being run today. It needs to output data that will go to the web instead of a standard report. At the time, I could have said, "Gee, that Al Gore discovery called the internet may take off some day. I should code my report program so that it can work with it." None of us are that forward-looking. Heck, we even coded 2-digit years back then. ;}. To code every program in a certain way in the event that it might be used in an unintended way later doesn't make sense. At least to me. Tom.

Guest.Visitor
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
To code every program in a certain way in the event that it might be used in an unintended way later doesn't make sense. Tom, I just want to know how much overhead Thread(*Serialize) adds. If very little, then I'll just start adding to every program as I maintain/create them. I guess Barbara will have to chime in here, but it looks like this article was written a few years ago. Chris.

Guest.Visitor
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Tom, Here's an example of a Java programmer wanting to call an existing RPG program and doesn't want to bother the RPG programmers. This is why I am saying just go ahead and code Thread(*Serialize). An ounce of prevention is worth a pound of cure. http://www.mcpressonline.com/mc?128@232.1KNKfHX1eQT.17@.6b36d670!SearchMark=2#2 Chris

Guest.Visitor
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Hi Chris, I read that thread. Not knowing the Java progammer's relationship with the shop such as being a permanent employee, a temp, etc., what I'm about to say may not apply. Any programmer should be hashing this out within the shop to come up with a standard instead of programming without bothering the RPG programmers. You can do whatever you want in your shop. Like you, I'd be interested in knowing the potential problems, if any, and make sure that you're not using a pound of prevention for an ounce of cure. Let me know if you run into any problems with putting Thread(*Serialize) in each program. It may be worth looking at. Thanks Chris, Tom.

Guest.Visitor
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
It seems to me that people here are choosing performance over data integrity. Which option do you think the CEO, CIO, CFO, stock holders, BOD, etc would prefer? I ran some tests. I encourge others to do the same. I ran several tests over a program with and without Thread(*Serialize), 5,000,000 iterations over several tests. The performance is nearly the same, sometimes the Thread(*Serialize) actually wins. I imagine that database I/O will the bottleneck in most RPG modules, not Thread(*Serialize). Sure wish Barbara would add some input... Chris

H.Boldt
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
ShanePoad asked: why bother creating threads if you can't actually de-serialize the work load? Good question. Let's back up for a moment. Threads are typically used when handling requests in a TCP/IP server application. If a request can be handled quickly, then an answer can be returned immediately. But if there might be some latency involved in putting together an answer (such as accessing disk storage), the preferred approach is to spawn off a thread. (You could start a new process too, but that has additional overhead that's often not necessary. Basically, you don't want to introduce any unnecessary delay in processing the request.) In the past, it was usually only the systems programmer who needed to worry about this. However, these days you have HTTP servers, which may well call out to application code. Now back to your question, which I'll rephrase slightly: Why use RPG code in a multi-threaded environment if it's going to block requests at the RPG procedure level? That is, allow only one invocation of any procedure to be active at one time, thus totally eliminating any advantage that multi-threading might give you? Hmmm... Hmmm... Hmmm... Here are two possible answers: 1) You don't want all your nice existing RPG code to go to waste. 2) You don't want to learn Java or C. (Or any of dozens of other languages that handle threading better.) Sorry, I can't think of any other reasons why you would use RPG in a threaded environment. But I'm sure others with a better knowledge of the language can help. Cheers! Hans (http://www.boldts.net/)

H.Boldt
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Ralph wrote: Just guessing here, but wouldn't *Serialize invoke overhead to make it thread safe (synchronization at some level), the same synchronize that must be used prudently in Java programs for performance reasons? It's important to understand why serialization is necessary in RPG programs. The RPG run-time environment uses static global variables. This is pretty much mandated by various language features, such as files, LR-off return, and RPG's exception model. If you had a program active in two threads without some sort of serialization, you couldn't avoid the possibility that one thread might read the value of some static global while another is half-way through modifying it. THREAD(*SERIALIZE) was added to RPG in recognition of the fact that it would be too difficult to synchronize on every read and update of every global variable used by the run-time environment. On the other hand, if your procedures were totally re-entrant and used no static globals, then thread safety isn't much of an issue, and you wouldn't have to worry about the overhead of synchronizing access to shared resources. If, for example, you were to write a TCP/IP server app in Java or C or Python, you would spawn off a thread to process the request. Each thread can run pretty much independently so long as they do not access any shared resources. Threads may block on files operations, but the synchronization will be handled by the operating system. If your procedures are re-entrant except for a few shared static globals, you can put access to these shared resources in critical sections to synchronize access to them. But that's not the same as putting your whole application into one big critical section. The bottom line is THREAD(*SERIALIZE) was added to RPG allow RPG procedures to be called from Java server apps. It is not by any stretch of the imagination a preferred approach to multi-threading. Multi-threading is simply best left to languages that can support re-entrancy. Cheers! Hans

H.Boldt
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Ralph wrote: ... I don't see anything that different going on between the languages. ... The difference is that in a language that supports thread-safety (http://en.wikipedia.org/wiki/Thread-safe), you can put access to global resources within small critical sections (http://en.wikipedia.org/wiki/Critical_section). Thus, two or more threads can run at the same time, blocking only when a critical section is reached. In RPG, if THREAD(*SERIALIZE) is coded, the entire module (and anything it calls too) is in a critical section, and only one invocation of any procedure within the module can be active within a process at one time. Which rather defeats any advantage multi-threading (http://en.wikipedia.org/wiki/Multi-threaded) can offer. See the difference yet? Cheers! Hans

H.Boldt
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Chris: I think I have to side with Tom here. Even if the additional overhead on THREAD(*SERIALIZE) isn't much, it would still be an unnecessary burden on modules that are not currently used in a threaded environment. As I mentioned before, since THREAD(*SERIALIZE) causes the entire module to block, it should never be considered a preferred programming technique anyways. Any potential use of RPG modules in a threaded environment should be examined very carefully. Cheers! Hans

H.Boldt
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Ralph wrote: The point is is that there's nothing magical about Java, you have to go in and put synchronization protection around anything that multiple threads will access, same as we're doing with RPG here. ... You're still not getting it, Ralph. Let's look at it another way. Let's say your threaded code does not access ANY shared static storage. Your code written in Java or C would need NO synchronization. The code is already fully re-entrant. On the other hand, even if you do not code any shared static variables in your RPG module, you would still need THREAD(*SERIALIZE) because of RPG's run-time environment. OK, now add one shared static variable to your Java or C code. Only accesses to that shared variable need to be put into a critical section. The code can run safely in multiple simultaneous threads, blocking ONLY when the critical section is reached. Meanwhile, your RPG code blocks on every entry into the module. The difference is the possibility of greater throughput in the multi-threaded environment. With several threads running at once, one thread can still be running while others are blocked on I/O requests. But with RPG code, while one thread is blocked on an I/O request, others are blocked before the code is even started! Thus, the threads implemented in Java or C (or any other thread-safe language) can often complete faster. Ralph also wrote: I think when Java invokes ILE, there ought to be something in ILE that implements a *Serialize wrapper unless a job directive overrides it for those that would really want to do that. One problem with this suggestion is that you also have to consider an RPG module invoked from RPG modules called from Java. There's a reason Barbara suggests putting THREAD(*SERIALIZE) on ALL modules that can be invoked from Java. That includes modules called by other RPG modules called from Java. Consider three modules A, B, and C. A and B are called directly from Java, and these call C. C needs THREAD(*SERIALIZE) as much as A and B since A and B may well be active at the same time and may try to call C at the same time. The bottom line is this: Multi-threading is not an easy concept to grasp fully. THREAD(*SERIALIZE) is an easy way for RPG programmers to stay out of trouble, but is far from optimal. Cheers! Hans

shane
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Thread stupid here asking a question. I currently submit separate jobs for my multi-user communications work and have wondered if threads could hide some of the ugliness of such a technique. I have simply assumed that the lack of threading discussions involving RPG meant threading had requirements better suited to C. If I write a threaded app, it would need a main and set of procedures to carry out the needed tasks. Are you saying the threads can't be running any of these procedures concurrently only serially. If I understand this, why bother creating threads if you can't actually de-serialize the work load? And then why doesn't the main have the same problems?

B.Morris
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Sorry, I didn't realize this discussion was going on. As Chris found in his tests, there is very little overhead from coding THREAD(*SERIALIZE). One problem I see with coding THREAD(*SERIALIZE) everywhere is that it might give the illusion that all the RPG code was now thread-safe. But it's not necessarily safe; coding *serialize just brings an RPG module to the same point as a module written in say a C module with no static storage. Ensuring thread-safety involves much more than just protecting the access to the static storage.

B.Morris
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Chris said: "4. Does coding Thread(*Serialize) still create just object? I swear I read a while back that this creates 2 objects, 1 hidden. " Then Tom said: "4. I remember hearing or reading the same thing. the second object somehow enforces the serialization. " What do you mean by "object"? Coding THREAD(*SERIALIZE) just causes the compiler to generate code to synchronize access to the module. At runtime, a mutex is created for each synchronized module. If the module runs in different activation groups, each AG would get its own mutex (since the static storage for each activation group is separate, the synchronization is also separate). The mutex isn't hidden though; you can see it in DSPJOB or WRKJOB, option 19.

R.Daugherty
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Just guessing here, but wouldn't *Serialize invoke overhead to make it thread safe (synchronization at some level), the same synchronize that must be used prudently in Java programs for performance reasons? Or is the assumption that there would no overhead unless it really was in a multi-threaded job? I have to think it affects the compiled object code but maybe does very, very little unless there are other threads to cause blocking. To me it's the same thing as saying why not put synchronize on every Java method just in case. I am writing my first Java thread and sockets code this weekend for sure. I've been saying that for several weekends but this weekend for sure. :) rd

R.Daugherty
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Another thought, in defense of RPG. Someone said that other languages like C and Java handle threading better, which is true, but some would walk away from the entirety of this thread thinking that Java and C handle threads and RPG doesn't, which is not the same thing at all. A sort of knee jerk C and Java know something that RPG doesn't would preclude why I am writing thread aware Java code this weekend. If Java is so much more advanced, why am I doing the equivalent of putting *Serialize in it? It's because there are performance costs to synchronize code, so we don't put synchronise around every block of Java code and *Serialize in front of every RPG program. But if you have designed a multi-threaded application, then you do. As I have asked elsewhere, just what would one do with threads in an ERP program except handling your own sockets communications anyway, and is it even desirable from an enterprise perspective? Remember, there is never anything new, just different tradeoffs. There is a reason we did what we did, and do what we do, and the tradeoffs that we chose in RPG. rd

R.Daugherty
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Thanks for the additional info, Hans. It's not clear to me how Java would be accessing RPG globals to require synchronization protection of all things RPG from Java to allow RPG procedures to be called from Java server apps. rd

R.Daugherty
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Chris, I read the article and the advice seems to preclude onerous overhead: Here are some rules of thumb: 1. Code THREAD(*SERIALIZE) in every module that might be run in a multi-threaded job. end quote rd

R.Daugherty
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Ok, I read the article. You would have to have more than one Java thread calling subprocedures from the same ILE RPG module, and it's to protect system RPG processing code variables from being overwritten by two RPG code executions simultaneously in the same ILE module. Might not even deal with your own variables, which you would have to deal with as in Java with two threads accessing same variable, but in that case you would write the Java code with the variable designed to be accessed simultaneously. In RPG a global variable accessed by two procedures may be assumed (as one would normally expect in RPG) that one procedure will complete before the other is called. On the other hand, the RPG global variable could be designed to be accessed by multiple procedures in the module simultaneously, called from multiple Java threads, just as Java variables are. It seems totally comparable to the same situation in Java if you run multiple threads and don't synchronize mutually accessed data. The same thing will happen. It's a good call out from Barbara, I don't see anything that different going on between the languages. People doing stuff at this level need to design for it. Plus while Java seems superior because a JVM is running multiple threads, my understanding is that IBM and others are desperately trying to create a JVM that can share much better as ILE does because of huge scaling problems with JVM's being launched for every job that don't scale the way ILE does. So sure, if you a big enough hog you might seem superior. As usual, depends on what tradeoffs you're willing to make. rd

R.Daugherty
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
The point is is that there's nothing magical about Java, you have to go in and put synchronization protection around anything that multiple threads will access, same as we're doing with RPG here. Yes, it may be just a little more practical to run one procedure at a time like reading a data queue and blocking to finish processing before reading another, instead of having a system that reads off the data queue as fast as presented and spawning a thread for each read, where we could go into the code and figure out what all may be used simultaneously and put synchronization opcodes around everything necessary. Wouldn't that be good ERP programming? I think there's a reason OS/400 architecture is a little more practical than that. Speaking of which, *Serialize appears to me to be the equivalent of a virtual data queue for calls. I can't imagine any RPG programmer that would expect that multiple threads calling procedures in a service program in the job would be allowed to come in and start executing before the first call finished under any condition. I think when Java invokes ILE, there ought to be something in ILE that implements a *Serialize wrapper unless a job directive overrides it for those that would really want to do that. rd

R.Daugherty
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Well, I did get it, but I chose to say that synchronizing at the module level and letting calls complete like reading a dataq is a good thing. The RPG to RPG on downstream in the thread I missed though, thanks for pointing that out. I also saw Barbara's explanation of the mutex mechanism. The automatic synching in hindsight is false protection, as only stateless subprocedures could be called from multiple threads, or web pages in the case of the jobs site server I wrote, without overwriting data from the other thread that was counted on being there next time it called. So *Serialization would the the easiest part of making sure a module was ready to participate in multiple threads. rd

MCWebsite.Staff
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
** This thread discusses the Content article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
0

David Abramowitz
12-31-1969, 06:33 PM
** This thread discusses the article: TechTip: Running RPG Programs in Multi-Threaded Jobs (http://www.mcpressonline.com/index.php?option=com_content&view=article&id=1471) **
Barbara Morris wrote: This causes the RPG compiler to generate code to ensure that only one thread can be running in any procedure in the module at any one time. I am by no means knowledgable in the area of threads but what I seem to know makes me believe that the aforesaid sentence appears to take away any reason for using threads at all. I'm afraid I need a bit of elaboration on this subject. Dave

Guest.Visitor
04-26-2006, 06:07 AM
Would it be possible to add a new function/opcode in future RPG to synchronize the update of global/static variables like synchronize; eval global_ctr += 1; end-synchronize; so that it would only block the statement that updates the global/static variable and not the whole module?

B.Morris
04-26-2006, 08:58 AM
The reason RPG needs the module-wide synchronization is because of the hidden static storage that the RPG compiler uses to make the RPG module work correctly. If the only static storage in the module was the static variables you declared yourself (including any global variables), then it would indeed be possible to have statement-level synchronization like you suggest.

Guest.Visitor
04-26-2006, 11:06 AM
Barbara, Thanks for all the feedback. In the book "Java at Work", on page 333, author Jim Barnes writes: Next I have coded a compiler directive at Label G that will enable me to use the same source code to generate both a threadsafe version of the service program and a single-threaded version for pure native applications. This is done to enable Java threads of execution to be serialized for each all instance of your native methods. Yet you will want to avoid serialization when other RPG programs call your service program. Maybe I read too much into this statement. Thoughts? Chris

Guest.Visitor
04-26-2006, 01:56 PM
Thanks to everyone who participated... Shane, Hans, David, Ralph, Chris, Gio, and Barbara for the article and her participation (hope I didn't leave anyone out). I now understand multithreading and serialization, and, may even be able to talk intelligently about them. Tom.

B.Morris
04-27-2006, 04:26 PM
Chris, that author was advocating explicitly building two versions of the service program, by coding something like the first example in the raw code below, and then compiling once without DEFINE(MULTI_THREAD) and once with it. I haven't seen that book, but if he was using the same source code for Java native methods and ordinary procedures, he probably also had something like the second example in the raw code for the prototypes for the native methods. If your procedure is a native method, you can't call it without Java being involved. A native method gets called through Java, like any other Java method, even if it's in the same module as the caller. If you were going to that trouble (and it seems like a good idea if you want to call your procedures either from Java or from RPG but not mixing the two), then it makes sense to condition THREAD(*SERIALIZE) with the same DEFINE. <hr width=50 align=left>Code ('http://www.mcpressonline.com/mc/showcode@@.6b36d62c/28')

Guest.Visitor
04-28-2006, 04:43 AM
Barbara, I think you figured it out. He was using JNI. So the solution is apparently to specify different object names on the compile. Do you happen to know if CLLE is threadsafe if called from Java? I'm wondering if Java should ever call a CLLE program. I think the odds of having a problem are small. One JVM would have to have multiple threads using the *same* iSeries connection job (right?). Chris

J.Pluta
04-28-2006, 05:56 AM
And that (multiple threads on one connection) doesn't work very well. The second will block on the first until its call completes. That's why I like to assign one connection job per HTTP session. Joe

Guest.Visitor
04-28-2006, 06:26 AM
Ha. Good to know Joe. Now we've come full circle. This tells me that OPM CL programs are threadsafe, because of the blocking. And why would I need to add Thread(*Serialize) then? Maybe all this is needed *outside* the context of an HTTP server (servlet engine). Chrhis

R.Daugherty
04-28-2006, 07:23 PM
I am thinking this problem would have cropped up quickly for a shop that was calling RPG utility routines in a service program from multiple threads in a Java program, probably same kind of work for each thread but they were launching a thread for each "job", if you will, versus let's say just a main line thread and a sockets communications thread. I take it from this discussion that one instance of the service program would be called into the job space of the Java program and multiple threads could be calling subprocedures in it at the same time at some point. It's probably pretty knarly because of timing of conflict and I gather doesn't cause a crash, but rather generates "unpredictable" results when there is a conflict, those results only seen as side effects at some point in output. Java people would launch an instance of their equivalent object for each thread, thus no conflict. We, having job oriented architecture where people parse work out to jobs, not threads, have a job ready program sucked into an architecture that wouldn't have any qualms generating as many instances of objects as they have threads. If there isn't, there needs to be an object wrapper interface to do the same thing with RPG programs. If it's good enough for Java, I don't see why we should be efficient and take the blame. rd