Reasonable multi-threaded design

I'm fairly certain that this is the sort of threading model that Apache/Tomcat uses, but I'm not positive. Just looking for some validation that this is a stable/scalable design and that there aren't any major problems with it.
Create static pool of listener threads all blocking on ServerSocket.accept()
On accept, check out a worker thread from a dynamic pool, pass it the socket and kick off the worker.
Worker checks self back in to pool upon job completion.
I'm using Jakarta commons pooling library if that make any difference.
Our old design has just one listener and much larger pool of workers, but the workers stayed bound to a particular client for at least 15 minutes, so the worker pool keeps growing as the server gets busier and busier. The new design should handle more clients with fewer resources because the worker thread is available for a different client immediately upon job completion.
Thoughts?

Oops wrong forum. Any way to move this or should I just repost?

Similar Messages

  • Crystal Report XI u2013 Multi Thread - function PEOpenEngineEx failed. Reason:

    In Crystal Report XI u2013 Multi Thread - function PEOpenEngineEx failed. Reason: Report engine not opened
    Hi
    I am using Crystal report XI with Delphi 7
    OS: Windows XP.
    Delphi 7
    CR Version: Crystal Report XI
    In Crystal Report XI While calling PEOpenEngineEx() by setting Engine option as multi thread, It failed with error message u201CError:512 Report Engine Not Openedu201D
    Code Change in Delphi 7 UCrpe32.pas (Crystal Reports XI Release 1 - Service Pack 3 and Service Pack 4)
    aEngineOptions.openEngineType := PE_OE_MULTI_THREADED;
    FEngineOpened := FCrpeEngine.PEOpenEngineEx(EngineOptions);
    I tried the same with Crystal Report 8.5 (above mentioned code change) Function PEOpenEngineEx() working fine.
    How to overcome this error to make work Multi Thread using CR XI?

    I found that it is bug Release 2 and the script server_patch_xir2 resolved it.

  • Multi thread D/B access design.

    Hi,
    I'm trying to performance test a 3 tiered design from client > TCP/IP to Server > ODBC to MSQL.
    I have a multi thread requesting client which connects via sockets to the server.
    The server kicks off multithread servelets which create a connection via ODBC ( Or reuse an existing one ) and communicates the data back to the requesting client.
    However, no matter the number of threads/ports/connections/ODBC data sources/Device managers I use I always get a linear progression for the data I am accessing.
    ie 1 file of 1000 records is 390 milliseconds, 10 is 4600 milliseconds etc.
    Is there somethings simple I'm missing out to make the access to the server linear ?
    The only option I'm considering at the moment is that the MSQL V 7.0 I have is the free one with visual studio and so has been "enhanced" to provide reduced performance.
    Any ideas ?
    Cheers,
    Gary

    The answer to you question is JDBC-ODBC BRIDGE IS SYNCHRONIZED..meaning it is SINGLE THREADED. No matter how many threads you create to access your database, only one thread enters the monitor at a time. The monitor I am referring to is the process space allocated to the thread at any given time, in your case I am referring to the process space as the particular lines of code which are responsible for database access. Your problem can be solved if you go for other database drivers( like type 4 drivers ). There are a variety of mutithreadd drivers available for most of the databases. I have raised this question at Sun Seminars also , and apparently this seems to be the only solution..
    Cheers,
    Shafique Razzaque,
    Senior Apps Developer,
    Singapore.

  • What's wrong with my multi-threaded Matrix Mult. code? 1 thread is fastest

    For some reason, 1 thread performs the best. What's wrong with my implementation?
    import java.util.Random;
    import java.util.Date;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    public class Matrix {     
         private int values[][];
         private int rows;
         private int columns;
         public Matrix(int r, int c) {
              this.rows = r;
              this.columns = c;
              this.values = new int[r][c];
         private void randomize() {
              Random generator = new Random();
              for (int r = 0; r < this.rows; r++) {
                   for (int c = 0; c < this.columns; c++) {
                        this.values[r][c] = generator.nextInt(10);
         public String toString() {
              String out = "";
              for (int r = 0; r < this.rows; r++) {
                   for (int c = 0; c < this.columns; c++) {
                        if (c == 0) out += "[";
                        else out += "\t";
                        out += this.values[r][c];
                   out += "]\n";
              return out;
         public boolean equals(Object obj) {
              Matrix other = (Matrix) obj;
              if (this.columns != other.columns || this.rows != other.rows)  {
                   return false;
              for (int r = 0; r < this.rows; r++) {
                   for (int c = 0; c < this.columns; c++) {
                        if (this.values[r][c] != other.values[r][c]) {
                             return false;
              return true;
         // matrix multiplication using single thread
         public Matrix times(Matrix other) {
              assert(this.columns == other.rows);
              Matrix out = new Matrix(this.rows, other.columns);
              for (int r = 0; r < this.rows; r++) {
                   for (int c = 0; c < other.columns; c++) {
                        int dotProduct = 0;
                        for (int z = 0; z < this.columns; z++) {
                             dotProduct += this.values[r][z] * other.values[z][c];
                        out.values[r][c] = dotProduct;
              return out;
         // matrix multiplication with many threads
         public Matrix ptimes(Matrix other, int numberOfThreads) throws InterruptedException { // parallel
              assert(this.columns == other.rows);
              Matrix out = new Matrix(this.rows, other.columns);
              ExecutorService threadExecutor = Executors.newFixedThreadPool(numberOfThreads);
              for (int r = 0; r < this.rows; r++) {
                   for (int c = 0; c < other.columns; c++) {
                        threadExecutor.execute(new HelperThread(r, c, this, other, out));
              threadExecutor.shutdown();
              threadExecutor.awaitTermination(2, TimeUnit.DAYS);
              return out;
         private class HelperThread implements Runnable {
              private int row;
              private int col;
              private Matrix a;
              private Matrix b;
              private Matrix out;
              HelperThread(int r, int c, Matrix a, Matrix b, Matrix o) {
                   this.row = r;
                   this.col = c;
                   this.a = a;
                   this.b = b;
                   this.out = o;
              public void run() {
                   int dotProduct = 0;
                   for (int z = 0; z < a.columns; z++) {
                        dotProduct += this.a.values[row][z] * this.b.values[z][col];
                   this.out.values[row][col] = dotProduct;
         public static void main(String[] args) throws InterruptedException {
              int size = 100;
              Matrix a = new Matrix(size, size);
              a.randomize();     
              Matrix b = new Matrix(size, size);
              b.randomize();
              for (int t = 1; t < 15; t++) {
                   long start = new Date().getTime();
                   System.out.print(t + " threads: ");
                   Matrix c = a.ptimes(b, t);
                   //System.out.println(c);
                   long finish = new Date().getTime();
                   System.out.println((finish - start) + " milliseconds");
                   Matrix d = a.times(b);
                   assert(c.equals(d));
    }

    This one is even faster. On my dual core I get:
    Warmup
    Single Threaded
    5.20616 milliseconds
    5.52872 milliseconds
    5.12708 milliseconds
    5.59048 milliseconds
    5.16104 milliseconds
    5.1838 milliseconds
    5.37104 milliseconds
    5.1788 milliseconds
    5.18636 milliseconds
    5.15736 milliseconds
    Multi Threaded with 2 threads
    3.22184 milliseconds
    2.86552 milliseconds
    2.86284 milliseconds
    3.67032 milliseconds
    3.08032 milliseconds
    2.97388 milliseconds
    2.93084 milliseconds
    3.44012 milliseconds
    2.89744 milliseconds
    2.88136 milliseconds
    As you can see the Multi-Threaded versions are now faster.
        // matrix multiplication with many threads
        ExecutorService threadExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        public Matrix ptimes(Matrix other) throws InterruptedException, ExecutionException {
            assert (this.columns == other.rows);
            Matrix out = new Matrix(this.rows, other.columns);
            Future futures[] = new Future[rows];
            for (int r = 0; r < this.rows; r++) {
                futures[r] = threadExecutor.submit(new HelperThread(r, this, other, out));
            for(Future f : futures) {
                f.get();
            return out;
        private class HelperThread implements Callable<Object> {
            private int row;
            private Matrix a;
            private Matrix b;
            private Matrix out;
            HelperThread(int r, Matrix a, Matrix b, Matrix o) {
                this.row = r;
                this.a = a;
                this.b = b;
                this.out = o;
            public String call() throws Exception {
                int dotProduct = 0;
                for (int c = 0; c < b.columns; c++) {
                    for (int z = 0; z < a.columns; z++) {
                        dotProduct += this.a.values[row][z] * this.b.values[z][c];
                    this.out.values[row][c] = dotProduct;
                return null;
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            int size = 100;
            Matrix a = new Matrix(size, size);
            a.randomize();
            Matrix b = new Matrix(size, size);
            b.randomize();
            System.out.println("Warmup");
            for (int t = 0; t < 1000; t++) {
                Matrix c = a.ptimes(b);
                Matrix d = a.times(b);
                assert (c.equals(d));
            System.out.println("Single Threaded");
            for (int t = 0; t < 10; t++) {
                long start = System.nanoTime();
                Matrix d = a.times(b);
                long finish = System.nanoTime();
                System.out.println((finish - start)/1000000.0 + " milliseconds");
            System.out.println("Multi Threaded with " + Runtime.getRuntime().availableProcessors() + " threads");
            for (int t = 0; t < 10; t++) {
                long start = System.nanoTime();
                Matrix c = a.ptimes(b);
                long finish = System.nanoTime();
                System.out.println((finish - start)/1000000.0 + " milliseconds");
                Matrix d = a.times(b);
                assert (c.equals(d));
            System.exit(0);
        }

  • Multi-thread failure - Error in assignment

    Hello
    I have a c++ program processor running under Windows XP with Oracle 9i. My program access to oracle by an ODBC driver version 9.2.0.4.0. It could be launched in multi-thread to increase performance. When I launch it with one thread everything is fine. When I use several threads I have problems. ODBC driver returns to me a "error in assignment ... General error" message and my updates queries failed. Under SQl server it works without problems. It seems to be a kind of deadlock. When I disable check box in my odbc driver of "enable query timeout" my program encounter a problem and freezes...
    Could someone help me ?

    user13335017 wrote:
    I have thought of the above solutions as workable, however, it is not. Some exhibited errors are:
    A. "Attempt to use database while environment is closed." This error applies to 2, 3 and 4 all the way;
    B. "Attempt to read / write database while database is closed." This error applies to 3 in particular;
    C. "Attempt to close environment while some database is still open." This error applies to 5.
    Please help me with designing a better strategy to solve the concurrent issue. Many thanks in advance.All these are expected errors. You should design the application so that you do not close an environment handle while database handles are still open, keep database handles open for as long as operations need to be performed on the underlying databases, open the database handles after opening the database handles, and close database handles before closing the environment handle.
    In short, in pseudo-code, you should have something like this:
    - open environment handle,
    - open database handles,
    - perform whatever operations are needed on the databases,
    - close database handles,
    - close environment handle.
    You can refer to the Getting Started with Data Storage and the Getting Started with Transaction Processing guides appropriate for the API you are using, from the Berkeley DB documentation page.
    Regards,
    Andrei

  • InfoPath: the multi-threading challenge

    Or to be more specific: calling a DataSource from a different thread.
    A project I'm working on includes an InfoPath form in which some heavy duty tasks are executed. These tasks can take over 10+ seconds to execute. To avoid the GUI to get stuck during execution, multi-threading is implemented. The problem lies in providing
    feedback to the user. Several methods have been used, but all end in the exceptions shown below.
    Unlike WinForms and such, InfoPath does not seem to provide a way to invoke the GUI. What we are trying to do is change field values to reflect the status of the process. This is done through the MainDataSource. I've tried several methods to call
    this datasource through another thread, like invoking a provided delegate, or execution context. However all these methods have similar results.
    When calling a method or property on the datasource the following exception is thrown:
    System.InvalidOperationException was unhandled
      Message="Operation is not valid due to the current state of the object."
      Source="Microsoft.Office.InfoPath.Client.Internal.Host"
      StackTrace:
           at Microsoft.Office.Interop.InfoPath.SemiTrust.ICLRExtensionsWrapper.IncrementSqmPoint(Int32 idDataPt)
           at Microsoft.Office.InfoPath.Internal.DataSourceHost.CreateNavigator()
           at Form1.FormCode.ContextCallbackMethod(Object obj) in E:\Projects\InfoPath Multithreading\Source\Form1\FormCode.cs:line 74
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at Form1.FormCode.ThreadMethod(Object myParamsObj) in E:\Projects\InfoPath Multithreading\Source\Form1\FormCode.cs:line 68
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart(Object obj)
    This seems to indicate the DataSource is locked for some reason. Even the ReadOnly property can not be read.
    When calling the SetValue method on an XPathNavigator provided by a datasource and passed through another thread, the following exception is thrown:
    System.AccessViolationException was unhandled
      Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
      Source="Microsoft.Office.InfoPath.Client.Internal.Host.Interop"
      StackTrace:
           at Microsoft.MsoOffice.InfoPath.MsxmlInterop.NativeHelpers.SetText(IXMLDOMNode* , Char* )
           at Microsoft.MsoOffice.InfoPath.MsxmlInterop.MsxmlNodeImpl.set_Text(String strText)
           at Microsoft.Office.InfoPath.MsxmlNavigator.SetValue(String value)
           at Form1.FormCode.DelegateMethod(XPathNavigator nav) in E:\Projects\InfoPath Multithreading\Source\Form1\FormCode.cs:line 81
           at Form1.FormCode.ThreadMethod(Object myParamsObj) in E:\Projects\InfoPath Multithreading\Source\Form1\FormCode.cs:line 70
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart(Object obj)
    I have searched through the internet but am unable to find any useful information about this subject. There are only a few weeks remaining before the deadline. A work-around has been implemented, but since it requires additional active user interaction
    it is far from ideal. I hope you can help me in finding a solution.

    For anyone who is still interested all this time later....
    I wouldn't use a Dispatcher in InfoPath simply because InfoPath requires .Net 2.0 only and Dispatcher was not added until .Net 3.0 which means you would have to enforce installation of .Net 3.0 yourself.
    There is an easy alternative which is SynchronizationContext (more specifically a WindowsFormsSynchronizationContext).
    Also I suggest you do not use ThreadStart but rather use one of the more modern and well known threading paradigms. A good alternative is a BackgroundWorker.
    e.g.
    private BackgroundWorker _Worker;
    public void InternalStartup()
    InitializeWorker();
    ((ButtonEvent)EventManager.ControlEvents["Button"]).Clicked += new ClickedEventHandler(ButtonClick);
    public void InitializeWorker()
    _Worker = new BackgroundWorker();
    _Worker.WorkerReportsProgress = true;
    _Rorker.WorkerSupportsCancellation = true;
    _Worker.DoWork += new DoWorkEventHandler(_Worker_DoWork);
    _Worker.ProgressChanged += new ProgressChangedEventHandler(_Worker_ProgressChanged);
    _Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_Worker_RunWorkerCompleted);
    public void ButtonClick(object sender, ClickedEventArgs e)
    if (_Worker.IsBusy)
    _Worker.CancelAsync();
    else
    // Very important to include this line!
    AsyncOperationManager.SynchronizationContext = new WindowsFormsSynchronizationContext();
    _Worker.RunWorkerAsync();
    void _Worker_DoWork(object sender, DoWorkEventArgs e)
    // Do stuff in another thread and report back to the UI thread.
    object state;
    int percentage = 0;
    _Worker.ReportProgress(percentage, state).
    public void _Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    // This is called on the thread that started the worker.
    // In this case the UI thread which means it is safe to use the MainDataSource.
    CreateNavigator().SelectSingleNode("my:Main/my:Progress", NamespaceManager).SetValue(e.ProgressPercentage);
    void _Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    // Do anything you want to do on completion here.
    One thing of note is that the SynchronizationContext in InfoPath for some reason or other always seems to be Null. The result is that when you call RunWorkerAsync() it captures the current synchronization context (null) which means the default is used and
    a ProgressChanged is called on a new thread each time. To prevent this we need to manually set the context before calling RunWorkerAsync() which is done using the AsyncOperationManager.

  • Using multi threading to access 2 RS232 ports

    Hi,
    I'm a beginner in multi threading, so this question may be a very basic one....
    I'm Using TS3.5 + CVI 8.01 to communicate withs 2 RS232 ports.  I thought to use mult threading so I can process 2 steps in parallel rather than in series. 
    This is what I do:
    1) I defined 2 subsequences, each of them call the same CVI function.  I use the sub sequence parameters to transfer the com number.
    2) My CVI application includes one dll for this specific project and another one, a general dll to handle RS232 functions.  The RS232 dll uses one global buffer than collects all the traffic on the com. 
    QUESTIONS:
    1) What happens when 2 seperate threads run the same function in the RS232 dll?  (in terms of memory etc...).  Does each one use a different buffer (in terms of memory allocation), or, both of them writes to the same buffer?   Obviously, if they writes to the same buffer, then, my function will not operate properly.
    2) What happens in TestStand after the 2 steps in new threads have finished their execution?  does the next step run back in the same threads the sequence run before?
    Thanks
    Rafi

    Rafi,
    Glad to hear you were able to make some ground on your application. As for all of your questions, I'll try to answer as many as I can.
    First, when you are talking about your global buffer, is it created in TestStand or in the DLL itself? When you use DLLs, global variables or global structures are shared between all threads that call your DLL. On the other hand, if your buffer is declared inside of the DLL it is global for the DLL but not shared and would be a separate buffer for each call.
    With your run-time error in TS, it would definitely be helpful to have more information about the error. From what you explained (executing fine on the first call, but failing on future executions), it sounds like the resource is not being released after the first execution.
    As far as a specific example for TestStand Multithreading, you'll want to look at the TestStand Development Library and, specifically, Multithreading in TestStand. If you look and browse through the Application Notes and Tutorials section, as well as the Technical Presentations section, you will learn a great deal about multithreading and what options you have in TestStand. For a specific example, you may want to look at This Example. You could also look in the <TestStand>\Examples (where <TestStand> is the directory where TS is installed) at the MultiUUT example for an example of multithreading in TS. These examples may not be exactly what you need, but they should give you a jump start.
    As far as making your DLL multithread safe, it is definitely not necessary; however, there are some significant advantages described in this article: Designing Thread-Safe DLLs. It is an MSDN article that focuses on Visual Basic, but it has some helpful information that can apply to C as well.
    Hopefully this can help you move further. I have attached a list of links at the end of this post with other helpful links for you as well. Keep us posted with your progress.
    Matt Mueller
    NI
    Links:
    General Information on Multithreading for C Programmers
    Building Multithreading Applications with LabWindows/CVI
    Multithreading in LabWindows/CVI
    Easy Multithreading Programming in LabWindows/CVI
    Multithreading for Rookies

  • Analysis for Office support multi thread?

    Does Analysis for Office support multi thread/core? If so, what verison? I tried searching around this site as well as note 1466118 - Hardware & Software requirements for Analysis, edition for MS Office but was unable to find an answer.
    I am on an Intel dual cpu with hyper threading turned on so it essentially looks like 4 cores. When I execute an Analysis View, I rarely see the EXCEL.EXE process go above 25% CPU utilization. I have plenty of RAM and hard drive space.
    64bit Windows 7
    32bit Office 2010
    AAO 1.3.5.2288
    Thanks

    I found the following info at:
    Excel 2010 Performance: Performance and Limit Improvements
    Large Data Sets and 64-bit Excel
    The 64-bit version of Excel 2010 is not constrained to 2 GB of RAM like 32-bit applications. Therefore, 64-bit Excel 2010 enables users to create much larger workbooks. 64-bit Windows enables a larger addressable memory capacity, and 64-bit Excel is designed to take advantage of that capacity. For example, users are able to fill more of the grid with data than was possible in previous versions of Excel. As more RAM is added to the computer, Excel uses that additional memory, allows larger and larger workbooks, and scales with the amount of RAM available.
    In addition, because 64-bit Excel enables larger data sets, both 32-bit and 64-bit Excel 2010 introduce improvements to common large data set tasks such as entering and filling down data, sorting, filtering, and copying and pasting data. Memory usage is also optimized to be more efficient, in both the 32-bit and 64-bit versions of Excel.
    Multi-Core Processing
    Additional investments were made to take advantage of multi-core processors and increase performance for routine tasks. Starting in Excel 2010, the following features use multi-core processors: saving a file, opening a file, refreshing a PivotTable (for external data sources, except OLAP and SharePoint), sorting a cell table, sorting a PivotTable, and auto-sizing a column.
    For operations that involve reading and loading or writing data, such as opening a file, saving a file or refreshing data, splitting the operation into two processes increases performance speed. The first process gets the data, and the second process loads the data into the appropriate structure in memory or writes the data to a file. In this way, as soon as the first process beings reading a portion of data, the second process can immediately start loading or writing that data, while the first process continues to read the next portion of data. Previously, the first process had to finish reading all the data in a certain section before the second process could load that section of the data into memory or write the data to a file.

  • Is a Trigger Multi Thread?

    I’m trying to execute a SELECT statement WHERE status = X to make some operations when I insert a row in my Table.
    If there is another insert until is execute the firs insert, the Trigger is executed in other Thread or waits until the first ended?
    Is a Trigger Multi Thread?
    If is multi thread, is possible to make it in single thread or wait until the first one end?

    Each session will execute its own copy of the trigger.
    To single thread access to rows within a table look at the select for update statement.
    When designing transactions give thought to Oracle's read consistency model: readers will not wait on updaters to see the row contents.
    But by selecting for update you will cause other sessions that want to update the same selected row as taken by the first session to wait for the first session to commit or rollback before the second session performs its update.
    If you need to single thread access to the entire table you could be designing an applciation that will not scale to support multiple session access.
    HTH -- Mark D Powell --

  • Is ABAP multi-threading safe?

    When implementing the Singleton design pattern in Java, we must use keyword <b>synchronized</b> with <b>getInstance()</b> method to ensure multi-threading safety, so that we can get the one and only instance.
        What shall I do in ABAP? or just leave it alone?  Would you help me find a example?
        thanks and regards,
      Davin,WANG

    Hi Davin,
    I do not understand fully what you are going to do in ABAP terms so I hope my comment will be of any value.
    Multithreading may be achieved in ABAB by calling a function with the addition STARTING NEW TASK IN GROUP.... See my sample program for <a href="https://wiki.sdn.sap.com/wiki/display/Snippets/Easilyimplementparallelprocessinginonlineandbatchprocessing">Easily implement parallel processing in online and batch processing</a>
    The second question may be solved by help of SAP lock concept. This is used primarily to secure a consistent database by not allowing two processes to change data at the same time. Chose a lock object of your choice and set at start of first instance. At end, remove the lock. Before creating the second instance, try so set the same lock. If you get a foreign lock error, you know the process is running.
    See documentation on lock objects on how to lock/unlock.
    Regards,
    Clemens
    Hope your internet connection is broken no longer so you can read this.

  • Aggregate Storage And Multi-Threading/Multi-Core Systems

    Please pardon if this question has been asked before, but the Forum search is not returning any relevant results.
    We are in the process of purchasing hardware for an 11.1.2 Essbase environment. We are going 64-bit, on Windows 2008, with either 32 GB or 64 GB of system RAM. The debate we are having is the number of CPUs and cores per CPU. We have not built any ASO databases as of yet, but we plan to launch a major BSO to ASO conversion project once 11.1.2 is off the ground here.
    Historically, with BSO, we did not see performance improvements significant enough to justify the cost of additional CPUs when we ran calcs on multi-CPU systems vs. single or dual CPU systems, even when the settings and design should have taken the most advantage of BSO's multi-threading capabilities. However, it would seem that ASO's design may be able to make better use of multi-core systems.
    I know that there are a lot of factors behind any system's performance, but in general, is ASO in 11.1.2 written well enough to make it worthwhile to consider, say, a four CPU, total 16 core system vs. a 2 CPU, total four core system?

    Grand central dispatch - infancy, not really doing its job, and I don't think apps have to be specifically written for HT, but they do have to not do things that they use to - prevent threads from going to sleep! or be parked.
    high usage is not necessarily high efficiency. often the opposite.
    Windows 7 seems to be optimized for multi-core thanks to a lot of reworking. Intel wants and knows it isn't possible to hand code, that the hardware has to be smarter, too. But the OS has a job, and right now I don't think it does it properly. Or handle memory.
    Gulftown's 12MB cache will help, and over all should be 20% more efficient doing its work.
    With dual processors, and it doesn't look like there are two quick path bridges, data shuffling has led to memory thrashing. Use to be page thrashing with not enough memory. Then core thrashing but having the cores, but not integrated (2008 is often touted as being greatest design so far, but it was FOUR dual-cores, 2009 was the first with a processor that really was new design and (native) 4-core.
    One core should be owned by the OS so it is always available for its own work and housekeeping.
    The iTunes audio bug last year showed how damaging and not to implement code and how a thread could usurp processing and add a high cpu temperature while basically doing nothing, sort of a denial of service attack on the processor - those 80*C temps people had.
    All those new technology features under development and not like OpenCL, GCD and even OpenGL are tested, mature but rather 1.0 foundation for the future. A year ahead of readiness.

  • What is multi threading?

    Hi all,
    What is multi threading? How to implement multi threading in ABAP?
    Regards,
    Bryan

    Hi
    How the vision connector framework works
    The connector interacts with an SAP application using connector modules. The connector modules make calls to SAP's Native Interfaces and pass data (business object or event data) to and from an SAP application. The connector's flexible design enables different modules to be used for different tasks such as initializing the connector with the SAP application or passing business object data.
    Communication between the connector and an SAP application
    The connector uses SAP's Remote Function Call (RFC) library to communicate with an SAP application. SAP's RFC API allows external programs to call ABAP function modules within an SAP application.
    Processing business objects
    The connector is metadata driven. Metadata, in the WebSphere business integration system, is application-specific data that is stored in business objects and that assists a connector module in its interaction with the application. A metadata-driven connector module handles each business object that it supports based on metadata encoded in the business object definition rather than on instructions hard-coded in the connector module.
    Business object metadata includes the structure of a business object, the settings of its attribute properties, and the content of its application-specific information. Because connector modules are metadata driven, they can handle new or modified business objects without requiring modifications to the connector-module code.
    The vision connector framework uses the value of the verb application-specific information in the top-level business object to call the appropriate connector module to process the business object. The verb application-specific information provides the classname of the connector module.
    The verb application-specific information of most top-level business objects must identify the classname of the connector module. The syntax of this verb application-specific information is:
    AppSpecificInfo = PartialPackageName.ClassName,
    For example,
    AppSpecificInfo = sap.sapextensionmodule.VSapBOHandler,
    In this example, sap.sapextensionmodule is the partial package name, and VSapBOHandler is the classname. The full package name includes the com.crossworlds.connectors prefix, which the WebSphere business integration system adds to the name automatically. In other words, the full text of the example is:
    com.crossworlds.connectors.sap.sapextensionmodule.VSapBOHandler
    Note:
    The verb application-specific information of most top-level business objects must use a comma (,) delimiter after the connector classname. However, the Server verb, which is used by the RFC Server Module, is delimited instead by a semi-colon (;). For information about the Server verb, see How the RFC Server Module works and Supported verbs.
    You need not specify the package name and classname for the verb application-specific information if the business object is used:
    by the ALE Module to process application events; however, when you use the ALE Module to process service call requests, you must specify the package name and classname
    by the ABAP Extension Module, which uses the default business object handler (sap.sapextensionmodule.VSapBOHandler)
    Important:
    Customer-generated connector modules that process business objects for the RFC Server Module must specify a full package name, which must begin with bapi. For example, bapi.client.Bapi_customer_getdetail2. The full package name in this example is bapi.client, and the classname is Bapi_customer_getdetail2.
    Most business object processing is specific to each connector module. By default the connector uses the ABAP Extension Module. For more information on business object processing for the ABAP Extension Module, see Installing and customizing the ABAP Extension Module and Business object data routing to ABAP handlers. .
    For more information on specifying verb application-specific information for the ALE Module, see Event processing and Processing multiple IDocs with a wrapper business object.
    Processing multiple concurrent interactions
    The Adapter Framework can create separate threads for processing an application event and a business object request. When processing multiple requests from the integration broker, it can create multiple threads to handle multiple business object requests. For example, when InterChange Server is the integration broker, the connector can receive multiple business object requests from multiple collaborations or from a multi-threaded collaboration.
    Figure 4 illustrates the multi-threading architecture.
    Figure 4. Multi-Threading Architecture of the Connector for SAP
    Event processing
    The connector performs the following steps when handling a poll call:
    The Adapter Framework creates a single dedicated thread to handle poll calls. This thread calls the pollForEvents() method of the vision connector framework at the frequency specified in the PollFrequency configuration property.
    The thread polls SAP, which uses a dialog process to locate and return the event.
    Note:
    If the connector's MaxNumberOfConnections configuration property evaluates to a number greater than 1, the vision connector framework dedicates a connection to SAP for polling. If MaxNumberOfConnections evaluates to 1, event and service-call request processing share a single connection to SAP.
    The polling thread dies only when the connector shuts down.
    Note:
    Because the RFC Server connector agent pushes events out of SAP instead of polling for events, it spawns its own threads instead of using threads created by the connector framework. Because the ALE connector agent uses the RFC Server connector agent to access events, it also spawns its own threads instead of using threads created by the connector framework when it processes events.
    Request processing
    Independently of polling, the Adapter Framework can create multiple request-processing threads, one for each request business object. Each request thread instantiates the appropriate business object handler.
    For example, when processing business object requests from InterChange Server, the number and type of business object handlers depends on the number and type of the collaborations sending the requests:
    If multiple collaborations send business objects, each request thread instantiates a business object handler of the appropriate type.
    If a multi-threaded collaboration sends multiple business objects of the same type, the request threads instantiate an equal number of business object handlers of that type.
    If the connector's MaxNumberOfConnections configuration property evaluates to a number greater than 1, the vision connector framework dedicates one connection to SAP for polling and allocates the remaining connections to a pool used only for request processing.
    As illustrated in Figure 4, the connector performs the following steps when handling a business object request:
    The Adapter Framework creates a separate thread for each business object request. Each thread calls the doVerbFor() method of the Vision business object handler.
    If the connector's MaxNumberOfConnections configuration property evaluates to a number greater than 1, the Vision business object handler checks the vision connector framework's connection pool to determine if a connection handle is available.
    If the handle is available, the thread sends the request to SAP, which uses a dialog process to handle the request.
    If the handle is not available, the thread waits until one becomes available. Thread sequencing determines the order in which each business object handler thread claims or waits for an available connection handle.
    If the connector's MaxNumberOfConnections configuration property evaluates to 1, the Vision business object handler shares a connection with event processing.
    SAP releases the dialog process after it completes processing and sends a return code.
    The connector releases the connection handle after it receives the return code from SAP.
    Setting the number of available connections
    Use the MaxNumberOfConnections configuration property to specify the maximum number of connection handles available. The number of connections cannot exceed the number of dialog processes.
    SAP locks the dialog process while processing an interaction, releasing it only when the interaction completes. Therefore, multiple concurrent requests lock an equal number of dialog processes until processing finishes.
    Important:
    Before setting a value for MaxNumberOfConnections, contact your SAP BASIS administrator to determine an appropriate value to maximize throughput without negatively affecting performance on the application server.
    Support for multiple connections
    By default the connector supports multiple-threads.
    <b>
    REWARD IF USEFULL</b>

  • Multi-threaded performance server using 2 ports to two-way communication

    Hi, I'm new in the forums so welcome everyone. I'm developing now an online computer game based on orginal Polish board-game, but it doesn't mean. Important is that I need to develope a high-performance multi-threaded server, which can serve... let's say few hundres of games, and a thousend of players simulateously. My server works on two ports/sockets.
    First one is represented by "ServerSocketChannel clientConSsc" in my code. The main thread in my server class which invokes the method "run()" (which You can see below), registers clientConSsc with Selector and then repeatingly accepts incoming connections from clients on this socket. When connection(channel) is estabilished and clients wants to write some request to this channel, the main thread on server creates a new instance of class "RequestHandler" which extends Thread and handles this request (reads the request from channel, makes some changes on server, spreads some new messages to other clients in the same game and so on... everything on the same socket/port/channel). Then the channel/connection is closed by the server - I call such connections: "a short connections". In the same time the main thread continues the loop and is still able to accept connections from another players. That's the idea of multi-threaded server, right? :) And to this point, everything works fine, but... what if the server wants to trigger some new command, write new information to client?
    Server could have tried to open a SocketChannel to client's IP address, but then the client programme would have to create and ServerSocketChannel object, bind it to some InetAddress and then... and then client becomes a server! - that breaks the idea of client-server cooperation and demands on players of my game to have routed some port on their machines. To resolve this problem I made some sort of "system" which, when some player/client is logging into my server, accepts second (this time constant, not "short") connection on the second port I mentoined on the beginning. This connection is held in variable "SocketChannel serverCon" of class "Player" - which reflects a player logged onto server. Server maintains every such connection till the client logs off. After the connection is accepted, the player whom connection it was is added to collection called "playersToRegisterToWrite". After the Selector.selectNow() is invoked (as You can see in the code below), each and every player's connection is registered in selector (with selection key - OP_WRITE and attachment pointing on owning player). In the same time client's code is trying to read some bytes from this connection and blocks on it until some bytes are written to this connection. When server wants to "tell" something to client, deliver some message/command, it creates a new instance of class which extends an abstract class called "ServerAction" (another new thread) and adds it to collection "actionsToDo". In ServerAction's method "run()" there are whole code to interact with client (e.g. send an update of players' list, an update of games' list, a chat message). Finnaly when Selector informs the server that some connection is writable (some client is waiting for commands), then server checks if there's any "actionToDo" involving this client/player. If there is, it unregisters the connection from Selector (so no other ServerAction (thread) can write on this connection) and starts the action. At the end of every "run()" method of subclass of ServerAction there's a code, which again adds the player to collection "playersToRegisterToWrite", so the player's connection can again be registered in Selector and the player can again receive informations from server - after it consumed THIS "ServerAction".
    It looks to me like it should be working fine, but it's not. When I test my server and clients on the same machine (no ping/latency) everything seems to be working fine. But when it comes to play my game with somebody even on LAN or through the Internet there comes the problems. My first socket I describe (and first type of connections - short connections) works perfectly fine, so the requests triggered by client are delivered and handled properly. But the second socket is cirppling. For example: the server triggers a command refering to an update of clients logged to server' list. It is triggered by Selector so the client should be ready to read data from server, so the server sends data! And the client never receives it... Why?
    It experimented a whole lot of time on SocketChannel's method "configureBlocking(boolean)", but it never helps. I think the client should always block it's listening thread on connection, contratry to server which is ment to be fast, so it should send the data through non-blocking channels. Am I right? Are there any rules refering blocking configuration of SocketChannels?
    I will be grateful for every answer. To help You out I attach also drafts from run()'s methods of my classes.
    Server's main method - main thread :
        public void run() {
           try {
                selector = Selector.open();
                clientConSsc.configureBlocking(false);
                clientConSsc.register(selector , SelectionKey.OP_ACCEPT);
                while(serverRunning) {
                    try {
                        selector.selectNow();
                        Iterator it;
                        synchronized(playersToRegisterToWrite) {
                            it = playersToRegisterToWrite.iterator();
                            while(it.hasNext()) {
                                Player player = (Player)it.next();
                                it.remove();
                                player.serverCon.configureBlocking(false);
                                player.serverCon.register(selector , SelectionKey.OP_WRITE , player);
                        Set keys = selector.selectedKeys() {
                        it = keys.iterator();
                        while(it.hasNext()) {
                            SelectionKey key = (SelectionKey)it.next();
                            if(key.isAcceptable()) {
                                it.remove();
                                clientCon = clientConSsc.accept();
                                clientCon.configureBlocking(false);
                                clientCon.register(selector , SelectionKey.OP_READ);
                                continue;
                            if(key.isReadable()) {
                                it.remove();
                                key.cancel();
                                new RequestHandler(this , (SocketChannel)key.channel()).start();
                                continue;
                            if(key.isWritable()) {
                                if(key.attachment() != null ) {
                                    ServerAction action = null;
                                    synchronized(actionsToDo) {
                                        Iterator aIt = actionsToDo.iterator();
                                        while(aIt.hasNext()) {
                                            ServerAction temp = (ServerAction)aIt.next();
                                            if(temp.getPlayer().equals((Player)key.attachment())) {
                                                action = temp;
                                                aIt.remove();
                                                break;
                                    if(action != null) {
                                        key.channel().configureBlocking(false);
                                        it.remove();
                                        key.cancel();
                                        action.start();
                                continue;
                    } catch(Exception e) {
                        statusArea.append(e.toString() + "\n");
                        e.printStackTrace();
                        continue;
            } catch(ClosedChannelException e) {
                statusArea.append(e.toString() + "\n");
            } catch(IOException e) {
                statusArea.append(e.toString() + "\n");
                A part of server's RequestHandler's class' method run() - the method which handles requests triggered by client on first port:
    public void run() {
            boolean served = false;
                try {
                    channel.configureBlocking(true);
                    retryCount++;
                    retry = false;
                    String command = ns.readText(channel).trim();
                    ns.statusArea.append("ktos przesyla komende: " + command + "\n");
                    if(command != null && !command.equals("ERROR")) {
                        String[] cmd = command.split("�");
                        ns.statusArea.append("komenda: " + cmd[0] + "\n");
                        if(cmd[0].equals("CHAT")) {
                            if(cmd.length != 5) {
                                retry();
                            } else {
                                if(cmd[2].equals("NOGAME")) {      // jezeli nie ma okreslonej gry czyli rozsylamy do wszystkich
                                    for(int i = 0 ; i < ns.loggedPlayersListItems.size() ; i++) {
                                        Player current = (Player)ns.loggedPlayersListItems.get(i);
                                        if(current.state == Player.CHOOSING && !current.equals(new Player(Integer.parseInt(cmd[1]))))   // jezeli gracz jest w okienku wybierania gry to wysylamy mu broadcast
                                            ns.actionsToDo.add(new SendMsg(ns , current , "CHAT�" + cmd[1] + "�" + cmd[3] + "�" + cmd[4]));
                                } else {
                                    Game game = (Game)ns.gamesListItems.get(ns.gamesListItems.indexOf(new Game(Integer.parseInt(cmd[2]))));
                                    for(int i = 0 ; i < game.players.size() ; i++) {
                                        Player current = (Player)game.players.get(i);
                                        if(!current.equals(new Player(Integer.parseInt(cmd[1]))))
                                            ns.actionsToDo.add(new SendMsg(ns , current , "CHAT�" + cmd[1] + "�" + cmd[3] + "�" + cmd[4]));
                                served = true;
                        } else if(cmd[0].equals("GETGAMEINFO")) {
                            if(cmd.length != 3)
                                retry();
                            else {
                                int gameID = Integer.parseInt(cmd[2]);
                                ns.statusArea.append("poproszono o informacje o grze nr: " + gameID + "\n");
                                Game checkedGame = new Game(gameID);
                                if(ns.gamesListItems.contains(checkedGame)) {
                                    Game game = (Game)ns.gamesListItems.get(ns.gamesListItems.indexOf(checkedGame));
                                    channel.configureBlocking(true);
                                    ObjectOutputStream oos = new ObjectOutputStream(channel.socket().getOutputStream());
                                    oos.writeObject(game);
                                    oos.writeObject(game.players);
                                    oos.flush();
                                    ns.statusArea.append("wyslano informacje o grze nr: " + gameID + "\n");
                                } else {
                                    ns.statusArea.append("brak gry o nr: " + gameID + "\n");
                                served = true;
                } catch(IOException e) {
                    e.printStackTrace();
            if(!served) {
                ns.findAndDisconnectPlayer(channel);
            try {
                channel.close();
            } catch(IOException e) {
                e.printStackTrace();
        }An example of ServerAction's subclass - the class which triggers server commands to client on second port:
    class UpdateLoggedPlayersList extends ServerAction {
        public UpdateLoggedPlayersList(NeuroServer ns , Player player) {
            super(ns , player);
        public void run() {
            try {
                serverCon.configureBlocking(true);
                ns.sendText("UPDATELOGGEDPLAYERSLIST" , serverCon);
                if(ns.readText(serverCon).equals("OK")) {
                    ObjectOutputStream oos = new ObjectOutputStream(serverCon.socket().getOutputStream());
                    oos.writeObject(ns.loggedPlayersListItems);
                    oos.flush();
                synchronized(ns.playersToRegisterToWrite) {
                     ns.playersToRegisterToWrite.add(player);
            } catch(IOException e) {
                e.printStackTrace();
    }A part of client's CmdHandler's class' method run() - the method which handles commands triggered by server:
    public void run() {
        try {
            while(works) {
                String command = nc.readText(nc.serverCon);
                System.out.println("Server przesyla komende: " + command + "\n");
                String[] cmd = command.split("�");
                if(cmd[0] != null && !cmd[0].equals("ERROR")) {
                    if(cmd[0].equals("CHAT")) {
                        if(nc.chooseGameDialog != null && nc.chooseGameDialog.isVisible()) {     // jezeli na wybieraniu gry
                            newChatEntry(cmd[2] , null , cmd[3] , nc.chooseGameDialog.chatPane);
                        } else if(nc.readyDialog != null && nc.readyDialog.isVisible()) {  // jesli na przygotowywaniu
                            Player sender = (Player)nc.actGame.players.get(nc.actGame.players.indexOf(new Player(Integer.parseInt(cmd[1]))));
                            newChatEntry(cmd[2] , sender.fraction , cmd[3] , nc.readyDialog.chatPane);
                        } else if(nc.ng != null) {                   // jesli w grze
                            Player sender = (Player)nc.actGame.players.get(nc.actGame.players.indexOf(new Player(Integer.parseInt(cmd[1]))));
                            newChatEntry(cmd[2] , sender.fraction , cmd[3] , nc.ng.inGameChatPane);
                    } else if(cmd[0].equals("UPDATELOGGEDPLAYERSLIST")) {
                        nc.sendText("OK" , nc.serverCon , false);
                        nc.serverCon.configureBlocking(true);
                        ObjectInputStream ois = new ObjectInputStream(nc.serverCon.socket().getInputStream());
                        DefaultListModel players = (DefaultListModel)ois.readObject();
                        nc.chooseGameDialog.updateLoggedPlayersList(players);
        } catch(IndexOutOfBoundsException e) {
            System.out.println(e);
        } catch(IOException e) {
            System.out.println(e);
        } catch(ClassNotFoundException e) {
            System.out.println(e);
    }And two methods I used in codes above: sendText(String text , SocketChannel sc) and readText(SocketChannel sc) - they are my "utility" methods, which I use to send and receive Strings through specified SocketChannels.
    boolean sendText(String text , SocketChannel sc) {
        ByteBuffer bbuf = ByteBuffer.allocate(BSIZE);
        boolean sendRetry;
        boolean sent = false;
        do {
            sendRetry = false;
            try {
                StringBuffer cmd = new StringBuffer();
                cmd.setLength(0);
                if(text.length()+4 < 100)
                    cmd.append("0");
                if(text.length()+4 < 10)
                    cmd.append("0");
                cmd.append(Integer.toString(text.length()+4) + "�");
                cmd.append(text);
                cmd.append("\n");
                bbuf = charset.encode(CharBuffer.wrap(cmd));
                sc.write(bbuf);
                bbuf.clear();
                int n = sc.read(bbuf);
                if(n == 1) {
                    bbuf.flip();
                    Byte re = bbuf.get();
                    if(re == 1) {
                        sendRetry = true;
                    } else {
                        sent = true;
            } catch(Exception e) {
                findAndDisconnectPlayer(sc);
                try {
                    sc.close();
                } catch(IOException f) {
                    f.printStackTrace();
                return false;
        } while(!sent && sendRetry);
        return true;
    String readText(SocketChannel sc) {
        ByteBuffer bbuf = ByteBuffer.allocate(BSIZE);
        int readRetryCount = -1;
        boolean readRetry;
        do {
            readRetry = false;
            readRetryCount++;
            StringBuffer cmd = new StringBuffer();
            cmd.setLength(0);
            bbuf.clear();
            try {
                readLoop:
                while(true) {
                    int n = sc.read(bbuf);
                    if(n > 0) {
                        bbuf.flip();
                        CharBuffer cbuf = charset.decode(bbuf);
                        while(cbuf.hasRemaining()) {
                            char c = cbuf.get();
                            if(c == '\r' || c == '\n') break readLoop;
                            cmd.append(c);
                    } else break;
                statusArea.append(Thread.currentThread().getId() + " readText() odczytuje: " + cmd.toString() + "\n");
                if(cmd.length() < 3 || Integer.parseInt(cmd.substring(0 , 3)) != cmd.length()) {
                    sc.write(ByteBuffer.wrap(new byte[] {1}));
                    readRetry = true;
                } else {
                    sc.write(ByteBuffer.wrap(new byte[] {0}));    // length OK
                    return cmd.toString().substring(4 , cmd.toString().length());
            } catch(Exception e) {
                findAndDisconnectPlayer(sc);
                try {
                    sc.close();
                } catch(IOException f) {
                    f.printStackTrace();
                return "ERROR";
        } while(readRetry && readRetryCount < 3);
        findAndDisconnectPlayer(sc);
        try {
            sc.close();
        } catch(IOException e) {
            e.printStackTrace();
        return "ERROR";
    }Edited by: Kakalec on Jul 23, 2008 11:04 AM

    You seem to be using a horrendous mixture of PrintWriters, BufferedReaders, ObjectOutputStreams, and no doubt ObjectInputStreams. You can't do that.
    Some rules about this:
    (a) Whenever you use a stream or reader or writer on a socket, you must allocate it once for the life of the socket, not every time you want to do an I/O.
    There are many reasons for this including losing buffered data in the old stream and auto-closure of the socket on garbage-collection of the old stream.
    (b) You can't mix stream types on the same socket. (i) If you're writing objects, use an ObjectOutputStream, you must read with an ObjectInputStream, and you can't read or write anything that isn't supported by the API of ObjectOutputStream. (ii) If you're writing lines, use a BufferedWriter and a BufferedReader at the other end. If you're writing characters, use a Writer and a Reader. (iii) If you're writing primitive data or UTF strings, use a DataOutputStream and a DataInputStream. (iv) If you're writing bytes, use DataOutputStream and a DataInputStream or an OutputStream and an InputStream. You can't mix (i), (ii), (iii), and (iv).
    (c) Don't use PrintWriter or PrintStream over the network. They swallow exceptions that you need to know about. They are for writing to the console, or log files, where you don't really care about exceptions.
    (d) Call flush() before reading.
    (e) Always close the 'outermost' output stream or writer of a socket, never the input stream or the socket itself. Closing any of these closes the socket and therefore makes the other stream unusable, but only closing the output stream/writer will flush it.

  • Trouble rationalizing use of multi-threading in run of the mill servlets

    Hey everybody,
    While spending time writing an internal wiki article on servlets for work, I asked myself a very basic question: What does multi-threading buy average servlets where the business logic requires procedural handling of the request?
    Don't get me wrong: I appreciate the fact that servlet containers spawning a new thread being less expensive than spawning an entirely new process is helpful and efficient. Coming from a background in PHP, it is great how servlets maintain persistence. However, as more of my coworkers are required to gain proficiency in Java and designing servlets, it is a question that many will ask and aside from having real-time processing of data files and other arduous tasks, I cannot think of any instances of where multi-threading benefits the application.
    What are some of the ways that you are using multi-threading with web applications?
    How would you explain why and where you would want to use multi-threading to someone?
    Thank you in advance for your insight,
    Andy

    how can we pass arguments to the run ()method?Create classes which implement Runnable that take your runtime parameters as constructor arguments and store them.
    eg: if your single thread method is   static void foo (int quantity, String name) {
        for (int i=0; i<quantity; i++) {
          System.out.println(name);
    // caller code
      foo(7, "wombats");Then you can make a runnable implementation thus:public class Foo implements Runnable {
      final int quantity_;
      final String name_;
      public Foo (int quantity, String name) {
        quantity_ = quantity;
        name_ = name;
      public void run () {
        for (int i=0; i<quantity_; i++) {
          System.out.println(name_);
    // caller code
      new Thread(new Foo(7, "wombats")).start();
    You could overload this method to take parameters in
    your class that implements the Runnable interface,
    and then call the base run() method.I don't get what you mean by this; Runnable is an interface so there is no base class run() method, and a run() overloaded with extra parameters method wouldn't get called by the thread.
    Pete

  • Multi-thread application recompile object with make but runs with old value

    Hi. I am working on a simulation in Java, and there is some behavior going on that I cannot understand. Granted, I'm a mechanical engineer, not a CS student (a fact that is probably made obvious by the code I'm posting below). The simulation comprises three parts: a controller, a robot, and a 3-d sensor. Here's the code for the "Simulation" application.
    class Simulation {
        void go() {
         ThreeDSensor sensorRunner = new ThreeDSensor();
         VSController controllerRunner = new VSController();
         KukaKR15SL robotRunner = new KukaKR15SL();
         Thread sensorThread = new Thread(sensorRunner);
         Thread controllerThread = new Thread(controllerRunner);
         Thread robotThread = new Thread(robotRunner);
         sensorThread.start();
         try {
             Thread.sleep(1000);  // Give sensorThread time to start in order to catch first triggers
         } catch(InterruptedException ex) {
             ex.printStackTrace();
         controllerThread.start();
         try {
             Thread.sleep(1000);  // Give controllerThread time to open the socket for communication with robotThread
         } catch(InterruptedException ex) {
             ex.printStackTrace();
         robotThread.start();
        public static void main(String[] args) {
         Simulation sim = new Simulation();
         sim.go();
    }I guess the big reason I'm using multi-threading is that once this simulation is working I want to be able to just run VSController alone and have it interface with a robot controller and a PC performing image processing. So with multiple threads I'm sending TCP and UDP messages around just like the final system will.
    I have made an object for my VSController that just stores values used by the simulation. That way I could have them all in one place instead of hunting through methods to change them. One example is "double noiseThreshold". Quickly, here is the code for "ControllerSettings.java".
    class ControllerSettings {
        final double cameraXOffset = 0;  // If > 0 then the origin of the camera CS is not on the center line of the lens
        final double cameraYOffset = 0;  // If > 0 then the origin of the camera CS is not on the center line of the lens
        final double cameraZOffset = 700;  // The distance that must be kept between the camera and the target
        // Error magnitude less than this is disregarded (in centimeters if roundingData else in millimeters)
        final double noiseThreshold = 60;
        final boolean estimatingEndPoints = false;  // If the controller is using two images per cycle then true
        final boolean roundingData = false;
        final boolean using3DData = true;  // How double[] sent from Matlab image processing is used
         * If the robot controller uses the output of this controller to command
         * motions in cartesian space then true.  This is used in two places: 1) initial guess of Jacobian,
         * and 2) "commandType" element sent to robot controller.
        final boolean useRobotControllerModel = false;
        final double thetaBumpValueForEstimationOfJacobian = .1;  // Distance each joint is jogged in estimation process
        final double bumpDistance = 50;  // Distance robot moves each time (magnitude of translation in mm)
        final double limitAngular = .5;  // Max amout robot joint will be commanded to rotate (in degrees)
    }And here is some pertinent code from "VSController.java".
    class VSController implements Runnable{
        ControllerSettings cSettings;  // Stores all the preferences used by the controller
        NGN controller;  // This is the controller algorithm.
        int dof;  // The degrees of freedom of the robot being controlled
        KukaSendData ksd;  // This provides communication to the robot.
        protected DatagramSocket socketForVisionSystem = null;
        ImageFeaturesData ifd;  // This parses and stores data from the image system.
        double[] errorVector;  // This is what's acted on by the algorithm
        PrintWriter errorTrackerOut = null;  // For analysis of error vector
        public void run() {
         VSController vsc = new VSController();
         vsc.go();
        public void go() {
         initWriters();
         cSettings = new ControllerSettings();
        public boolean isNoise() {
         boolean ret = false;
         double magnitude = 0;
         for (int i = 0; i < errorVector.length; i++) {
             magnitude += errorVector[i] * errorVector;
         magnitude = Math.sqrt(magnitude);
         if (magnitude <= cSettings.noiseThreshold) {
         System.out.println("VSController: magnitude (of errorVector) = " + magnitude +
                   ", threshold = " + cSettings.noiseThreshold); // Debug
    Now here's my issue: I change the value for "noiseThreshold" in "ControllerSettings.java" then run make from terminal (makefile code posted below) and rerun "Simulation". However, despite my changes to "ControllerSettings.java" the value for "noiseThreshold" is not changed, as evidenced by the output on the terminal screen:VSController: magnitude (of errorVector) = 6.085046125925263, threshold = 10.0 See, that value of 10.0 is what I used to have for noiseThreshold. I do not know why this value does not update even though I save the java file and execute make in between executions of Simulation. I would love it if someone could explain this problem to me.
    Here's the contents of makefile.
    JFLAGS = -cp ../Jama\-1\.0\.2.jar:../utils/:/usr/share/java/vecmath\-1\.5\.2.jar:.
    JC = javac
    .SUFFIXES: .java .class
    .java.class:
         $(JC) $(JFLAGS) $*.java
    CLASSES = \
         ControllerSettings.java \
         ImageFeaturesData.java \
         KukaKR15SL.java \
         ../utils/KukaSendData.java \
         NGN.java \
         Puma560.java \
         Robot.java \
         RobotSettings.java \
         Simulation.java \
         SimulationSettings.java \
         SixRRobot.java \
         Targets.java \
         TargetsSettings.java \
         ThreeDData.java \
         ThreeDSensor.java \
         VSController.java
    default: classes
    classes: $(CLASSES:.java=.class)
    clean:
         $(RM) *.classEdited by: raequin on Apr 5, 2010 1:43 PM

    I saw this explanation about what's causing my problem.
    "When the Java compiler sees a reference to a final static primitive or String, it inserts the actual value of that constant into the class that uses it. If you then change the constant value in the defining class but don't recompile the using class, it will continue to use the old value."
    I verified that the value updates if I also change something in VSController.java, forcing it to recompile. I think I will solve this problem by just making the variables in ControllerSettings no longer final (and then recompile VSController to make sure it takes effect!). Is there another solution? I saw intern(), but that seems to only apply to Strings.
    Thanks.

Maybe you are looking for

  • I work from home and connect to my work via VPN.

    Recently, I was being locked out several times a day.  It was discoved that my Mac-Mini is trying to connect to my work network, but I have never set anything up for this to happen.  How can I stop this?  I set up on my Mac Mini a app called PocketCl

  • Properties class not available on remote stylesheet

    dreamweaver cc will not apply style classes if the  css is on remote server.  I have to download the style sheet in order for the classes to appear in the properties/class dropdown tool.  what happened to live view and how do I change this so it work

  • Importing Opportunities and Sales Stage

    Hi, As part of our rolling out CRM to a new department we want to import some data from the current system that they use. The problem is that in our current model we use the "# Days in Stage" analytic value for some of our reports and calculations. I

  • My phone is malfunctioning.

    This morning I wake up and my phone is stuck on silent/vibrate [the side button is doing nothing], and it keeps switching from vibrate to on over an over again without touching a thing. Both speakers on my phone are gone, no sound will come out of ei

  • Clarification on OKB9 settings

    Hi Expert, Our client was using verion 4.7 and it is upgraded to version Ecc6. Yesterday we have created New Gl account and replaced with the eisting GL account. Existing GL account was not a cost element still it was assigned in OKb9, New Gl account