I found a workaround!!! Just rewrite everything in pure Java. :-)

Seriously, the following example works! And without having to make all Java 
methods static. The trick is to use Java threads rather than Perl fork() or 
threads.

-------

use Inline (
   Java => 'DATA',
   PORT => 17891,
) ;

my $nb = $ARGV[0] || 10 ;
for (my $i = 0 ; $i < $nb ; $i++){
   $test[$i] = new test($i);
}

$starttime = time;
for (my $i = 0 ; $i < $nb ; $i++){
   $test[$i]->start();
}
for (my $i = 0; $i < $nb; $i++){
   $test[$i]->join();
}
$elapsed = time-$starttime;

print "For $nb threads it took $elapsed seconds\n";

__DATA__
__Java__
class test extends Thread {
   String label;
   public test(String label) { this.label = label; }
   public void run() {
      try {
         System.err.println("start " + label);
         Thread.sleep(5000) ;
         System.err.println("end " + label);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
   }
}

---------------

$ perl ptest4.pl 50
start 0
start 1
start 2
...
end 47
end 48
end 49
For 50 threads it took 5 seconds


-----Original Message-----
From: Davis, Scott 
Sent: Monday, January 03, 2011 11:54 AM
To: 'Patrick LeBoutillier'
Cc: inline@perl.org
Subject: RE: How to make Inline::Java work in parallel ?

Hi Patrick,

Thanks for writing back! I am calling from Perl to Java only. Here is a closer 
example to what I am doing. I want to create several objects in the main 
process, and then execute methods in parallel in sub-processes. There are 
several steps to what I am doing, and I want to ensure that the first step 
completes on all target servers before moving on to the second step, and so 
forth.

use Inline (
        Java => 'DATA',
        SHARED_JVM => 1,
        PORT => 17891,
) ;
Inline::Java::capture_JVM() ; # Kill JVM on exit

my $nb = $ARGV[0] || 5 ;
for (my $i = 0 ; $i < $nb ; $i++){
        $test[$i] = new test;
}

$starttime = time;
for (my $i = 0 ; $i < $nb ; $i++){
        my $pid = fork;
        if (! $pid)
        {
                print "start $i\n";
                #Inline::Java::reconnect_JVM() ;
                $test[$i]->sleep();
                print "end $i\n";
                exit;
        }
        else
        {
           push @pid, $pid;
        }
}

waitpid $_,0 for @pid;

$elapsed = time-$starttime;
print "For $nb threads it took $elapsed seconds\n";

__DATA__
__Java__
class test {
        public test() { }
        public void sleep() throws InterruptedException {
                Thread.sleep(1000) ;
        }
}

---------------

$ perl ptest3.pl 2
start 0
start 1
end 0
end 1
For 2 threads it took 2 seconds
$ perl ptest3.pl 5
start 0
start 1
start 2
start 3
start 4
end 0
end 1
end 2
end 4
end 3
For 5 threads it took 5 seconds
$ perl ptest3.pl 10
start 0
start 1
start 2
start 3
start 4
start 5
start 6
start 7
start 8
start 9
end 0
end 3
end 6
end 1
end 8
end 9
end 5
end 7
end 2
end 4
For 10 threads it took 10 seconds

Note that when I uncomment the reconnect_JVM() line, then I get an error 
message:
$ perl ptest3.pl 2
start 0
start 1
Can't find object 1 for thread IJST-#1 at (eval 13) line 215
 at ptest3.pl line 24
Can't find object 2 for thread IJST-#2 at (eval 13) line 215
 at ptest3.pl line 24
For 2 threads it took 0 seconds

Thanks,
Scott

Reply via email to