How to test for if statement while executing while loops - java

I'm having to produce code whereby a Finch robot follows around an object after it is activated via a tap, and the program quits when it is tapped twice. I can't understand how I could do this. Right now, I'm trying to make it so that after the robot has been activated (it would be after the while(x==1) code), it will add 1 to 'tappedCount' each time the robot is tapped.
However, as the program will just about always be working within the other 'while' loops (which are within the if statements which check where the object is, one of these will always be activated due to the nature of the Finch. This means that the:
if(myf.isTapped())
{
tappedCount++;
}
if(tappedCount==2)
{
System.out.println("Exiting Finch");
System.exit(0);
myf.quit();
}
code never gets a chance to run.
Does anyone have suggestions as to how I could get that to run? or an alternative way to quit the program when the robot is tapped twice would be great. Thanks.
import edu.cmu.ri.createlab.terk.robot.finch.Finch;
public class FinchCode {
static long instant1;
static long instant2;
static long instant3;
static long instant4;
static long duration;
static long duration1;
static int x = 0;
static int Buzz = 300;
static int BuzzDuration = 1200;
static int R = 250;
static int G = 250;
static int velocityLeft = 150;
static int velocityRight = 150;
static int turnLeft = -100;
static int turnRight = -100;
static int time = 0;
static int tappedCount = 0;
static int millis;
public static void main(String[] args) throws InterruptedException{
Finch myf = new Finch();
while(!myf.isBeakDown())
{
if(myf.isTapped()&& x==0)
{
if(myf.isObstacleLeftSide()&&myf.isObstacleRightSide())
{
x = 1;
myf.setLED(R,0,0);
myf.stopWheels();
}
}
while(x==1)
{
if(myf.isTapped())
{
tappedCount++;
}
if(tappedCount==2)
{
System.out.println("Exiting Finch");
System.exit(0);
myf.quit();
}
if(!myf.isObstacleLeftSide()&&!myf.isObstacleRightSide())
{
while(!myf.isObstacleLeftSide()&&!myf.isObstacleRightSide())
{
myf.setLED(0,G,0);
myf.setWheelVelocities(velocityLeft, velocityRight);
}
System.out.println("Forward");
}
if(!myf.isObstacleLeftSide()&&myf.isObstacleRightSide())
{
while(!myf.isObstacleLeftSide()&&myf.isObstacleRightSide())
{
myf.setLED(0,G,0);
myf.setWheelVelocities(velocityLeft, turnRight);
}
System.out.println("Right");
}
if(myf.isObstacleLeftSide()&&!myf.isObstacleRightSide())
{
while(myf.isObstacleLeftSide()&&!myf.isObstacleRightSide())
{
myf.setLED(0,G,0);
myf.setWheelVelocities(turnLeft, velocityRight);
}
System.out.println("Left");
}
if(myf.isObstacleLeftSide()&&myf.isObstacleRightSide())
{
while(myf.isObstacleLeftSide()&&myf.isObstacleRightSide())
{
myf.setLED(R,0,0);
myf.stopWheels();
}
System.out.println("Stop");
}
}
}
}

boolean move = false;
if(myf.isTapped())
{
move = true;
}
while(move)
{
//Code keeping the finch moving
//check at the end of loop if the tapp has occured yet
//if so reset to false, and the while loop will exit
if(myf.isTapped())
{
move = false;
}
}
//Exit program and print your stuff
System.out.println("Exiting Finch");
System.exit(0);
myf.quit();

Related

Java Multithreading two classes in main

I am very new to programming, and I am trying to write a Java program with the Timer and ChecksUserInput classes shown below. How do I get them to run at the same time in the main class?
I am also having issues with printing out the word length in ChecksUserInput.
main.java:
package application;
public class Main {
public static void main(String[] args) {
CreateBoard board = new CreateBoard();
board.run();
Timer timer = new Timer();
timer.run();
ChecksUserInput input = new ChecksUserInput();
input.run();
}
}
timer.java:
package application;
public class Timer {
private static void time() {
final int mili = 1000;
final int sec = 60;
final int oneMinute = (mili * sec);
System.out.println("Start 3 minute timer");
sleep(oneMinute * 2);
System.out.println("One minute remaining...");
sleep(oneMinute);
System.out.println("Time's up!");
}
private static void sleep(int sleepTime) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
time();
}
}
checksuserinput.java:
package application;
import java.util.*;
public class ChecksUserInput {
private static String UserInput() {
Scanner sc = new Scanner(System.in);
System.out.println("Begin entering words!");
String word = null;
for (int i = 0; i < 10000; i++) {
word = sc.nextLine();
}
return word;
}
private static int length(String word) {
int wordLength = word.length();
return wordLength;
}
public void run() {
String userWord = UserInput();
int wordLength = length(userWord);
System.out.println(wordLength);
}
}
The foundation of multi-threading in Java is the Thread class. The general structure for usage is:
Thread newProcess = new Thread(processToRun); //Create a thread which will execute the process
newProcess.setDaemon(true/false); //when false, the thread will keep the JVM alive beyond completion of 'main'
newProcess.start(); //Start processToRun in a new thread
To start several independent processes, this should be sufficient. For example, the following starts 10 threads each of which will print the index in the loop. At the end, the process sleeps for 5 milliseconds because the spawned threads are daemon. Removing this may cause the process to terminate before any messages are printed.
public static void main(String args[]) throws Exception
{
for(int i = 0; i < 10; i++) { int index = i; start(() -> System.out.println(index)); }
Thread.sleep(5);
}
public static void start(Runnable processToRun)
{
Thread newProcess = new Thread(processToRun);
newProcess.setDaemon(true);
newProcess.start();
}
Beyond this point questions start to get more complicated/contextual. Ex:
How can processes running in 2 threads communicate with each other?
How can processes running in 2 threads access/modify common state between them?
In the context of creating a simple game, one option is to use Queues to feed user inputs to the game and have the game process updates in a single thread. The following sample listens for the user inputting commands (Up, Down, Left, Right) on the main thread and adds valid commands to a queue. Valid commands are polled and processed in a different thread to update the location on the board.
Sample:
public static void main(String args[])
{
Board board = new Board();
BlockingQueue<Move> movesQueue = new ArrayBlockingQueue<>(100);
Scanner systemListener = new Scanner(System.in);
start(() -> routeBoardMovesToQueue(board, movesQueue)); /*route moves from the queue to the board in a new thread*/
while(true)
{
Optional<Move> nextMove = Move.resolve(systemListener.nextLine());
if(nextMove.isPresent())
movesQueue.offer(nextMove.get()); /*Write moves from System.in to the queue*/
else
System.out.println("Invalid Move Provided");
}
}
public static void routeBoardMovesToQueue(Board board, BlockingQueue<Move> movesQueue)
{
try
{
while(true)
{
Move next = movesQueue.poll(100_000, TimeUnit.DAYS);
if(next != null) board.performMove(next);
}
}
catch(InterruptedException ignored){ System.out.println("Stopping"); }
}
public static void start(Runnable processToRun)
{
Thread newProcess = new Thread(processToRun);
newProcess.setDaemon(true);
newProcess.start();
}
public static final class Board
{
private final Location location;
public Board(){ this.location = new Location(); }
public void performMove(Move move)
{
switch(move)
{
case Up: location.y += 1; break;
case Down: location.y -= 1; break;
case Right: location.x += 1; break;
case Left: location.x -= 1; break;
}
System.out.println("New Position: (" + location.x + ", " + location.y + ")");
}
public static class Location{ int x = 0; int y = 0; }
}
public enum Move
{
Up, Down, Left, Right;
public static Optional<Move> resolve(String move){ return Stream.of(Move.values()).filter(mv -> Objects.equals(move, mv.name())).findAny(); }
}
You should search "java multithreading" on your favourite search engine and compare your code with those examples
You will find that these people have (mostly) implemented the Runnable interface on their classes.
So
-- public class ChecksUserInput {
++ public class ChecksUserInput implements Runnable{
And run() was a method of that interface, that they had to implement.
Your version first runs the run method of the first class, then the other.
But when you implement the runnable interface, the both run methods will be called right after one another, without waiting for the first one to finish
You should search on your own and find more examples, or check the documentations for multithreading if you face any other issues
So after the wonderful help #BATIKAN BORA ORMANCI and #mike1234569 gave me along with this link https://www.geeksforgeeks.org/multithreading-in-java/ I was able to actually figure it out
package application;
public class Main {
public static void main(String[] args) {
CreateBoard board = new CreateBoard();
board.run();
Thread timer = new Thread(new Timer());
Thread input = new Thread(new ChecksUserInput());
timer.start();
input.start();
try {
timer.join();
input.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
and I set my classes to implement Runnable as Batikan suggested

Java - Learning the difficulties with synchronized

So my teacher posted some code with examples of synchronized code and non synchronized and he is trying to teach us the differences between putting synchronized on a method and a block of code. I dont see the difference in his code by running the application but perhaps you guys can see it and explain. Ill post the code and if there is something missing with the information that im giving you guys just leave a comment and i will edit as soon as possible. So there are two classes which are related to each other. And these are the following. The commented methods are the one that im supposed to try. So the first method im supposed to run with synchronized public int incCounter() { and without. The rest of the methods im supposed to run without synchronizing public int incCounter() {. But i dont see the difference.
package f6;
public class Counter1Thread extends Thread {
private Counter1 counter;
private int times;
public Counter1Thread(Counter1 counter, String name, int times) {
this.counter = counter;
this.setName(name);
this.times = times;
}
// Testa med Counter1-incCounter a) utan synchronized b) med synchronized
// public synchronized void run() {
// int value;
// System.out.println(getName() + " startar");
// while (times-->0) {
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {}
// value = counter.incCounter();
// System.out.println(getName()+": "+value);
// }
// }
// testa med Counter1-incCounter utan synchronized
// public synchronized void run() {
// int value;
// System.out.println(getName() + " startar");
// while (times-->0) {
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {}
// synchronized(counter) {
// value = counter.incCounter();
// }
// System.out.println(getName()+": "+value);
// }
// }
// testa med Counter1-incCounter utan synchronized
// public void run() {
// int value;
// System.out.println(getName() + " startar");
// while (times-->0) {
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {}
// synchronized(counter) {
// value = counter.incCounter();
// System.out.println(getName()+": "+value);
// }
// }
// }
public static void main(String[] args) {
Counter1 counter = new Counter1();
Counter1Thread ct1 = new Counter1Thread(counter,"A",20);
Counter1Thread ct2 = new Counter1Thread(counter,"B",20);
ct1.start();
ct2.start();
}
}
package f6;
import java.util.Random;
public class Counter1 {
private int counter;
private Random rand = new Random();
public int incCounter() {
counter = counter + 1;
return counter;
}
// public synchronized int incCounter() {
// counter = counter + 1;
// return counter;
// }
}
The synchronized on the run methods don't do anything in these examples. You should ignore these. They are at best an example of randomly and incorrectly placed synchronization statements.
The key differences between the implementations are the differences between the (commented out) examples one and three: Example one has no synchronization around the increment operation, while the third example wraps increment with a synchronized statement:
value = counter.incCounter();
System.out.println(getName()+": "+value);
synchronized (counter) {
value = counter.incCounter();
System.out.println(getName()+": "+value);
}
The third example is the equivalent of the fourth example:
public synchronized int incCounter() {
counter = counter + 1;
return counter;
}
Which is the same as:
public int incCounter() {
synchronized (this) {
counter = counter + 1;
return counter;
}
}
Note that this from this fourth example is the same as counter from the third example.
What you should see is that the un-synchronized example doesn't reliably increment the counter. (You may not see the effect every time you run the test, as the result will depend on the timing of the two threads which are used by the test.)

Thread waiting to multiple threads

I have to create a hedge simulator. There is eg. 10 segments of it and each of them should have its own dedicated Thread simulating grow of the segment (each time we're about to calculate whether segment growed up, we should perform random test).
In addition there should be one additional, gardener Thread.
Gardener should cut segment of hence, when its size reaches 10 (then he cuts its size back to initial level of 1 and adds notifies it in his notes).
My attempt to make it working was like this:
public class Segment implements Runnable {
private int currentSize;
#Override
public void run() {
if(Math.random() < 0.3)
incrementSize();
}
private synchronized void incrementSize() {
currentSize++;
}
public synchronized int getCurrentSize() {
return currentSize;
}
public synchronized void setCurrentSize(int newSize) {
currentSize = newSize;
}
}
public class Gardener implements Runnable {
private int[] segmentsCutAmount = new int[10]; //Gardener notes
private Collection<Segment> segments;
public Gardener(Collection<Segment> segmentsToLookAfter) {
segments = segmentsToLookAfter;
}
#Override
public void run() {
while(true) {
//Have no idea how to deal with 10 different segments here
}
}
}
public class Main {
private Collection<Segment> segments = new ArrayList<>():
public void main(String[] args) {
Main program = new Main();
for(int i = 0; i < 10; i++)
program.addSegment();
Thread gardenerThread = new Thread(new Gardener(program.segments));
}
private void addSegment(Collection<Segment> segments) {
Segment segment = new Segment();
Thread segmentThread = new Thread(segment);
segmentThread.start();
segments.add(segment);
}
}
I am not sure what am I supposed to do, when segment reaches max height.
If there was 10 gardeners, every of them could observe one segment, but, unfortunelly, gardener is a lonely shooter - he has no family and his friends are very busy and are not willing to help him. And are you willing to help me? :D
I generally know basics of synchronization - synchronized methods/blocks, Locks, wait and notify methods, but this time I have totally no idea what to do :(
Its like horrible deadlock! Of course I am not expecting to be spoonfeeded. Any kind of hint would be very helpful as well. Thank you in advance and have a wonderful day!
About that queue. You can use the ExecutorService for that.
Letting the Hedge grow
So let's you have a hedge that can grow and be cut.
class Hedge {
private AtomicInteger height = new AtomicInteger(1);
public int grow() {
return height.incrementAndGet();
}
public int cut() {
return height.decrementAndGet();
}
}
And then you have an environment that will let the hedge grow. This will simulate the hedge sections; each environment is responsible for one of the sections only. It will also notify a Consumer<Integer> when the hedge size has gone.
class SectionGrower implements Runnable {
public static final Random RANDOM = new Random();
private final Hedge hedge;
private final Consumer<Integer> hedgeSizeListener;
public SectionGrower (Hedge h, Consumer<Integer> hl) {
hedge = h;
hedgeSizeListener = hl
}
public void run() {
while (true) { // grow forever
try {
// growing the hedge takes up to 20 seconds
Thread.sleep(RANDOM.nextInt(20)*1000);
int sectionHeight = hedge.grow();
hedgeSizeListener.accept(sectionHeight);
} catch (Exception e) {} // do something here
}
}
}
So at this point, you can do this.
ExecutorService growingExecutor = Executors.newFixedThreadPool(10);
Consumer<Integer> printer = i -> System.out.printf("hedge section has grown to %d\n", i.intValue());
for (int i = 0; i < 10; i++) {
Hedge section = new Hedge();
Environment grower = new SectionGrower(section, printer);
growingExecutor.submit(grower::run);
}
This will grow 10 hedge sections and print the current height for each as they grow.
Adding the Gardener
So now you need a Gardener that can cut the hedge.
class Gardener {
public static final Random RANDOM = new Random();
public void cutHedge(Hedge h) {
try {
// cutting the hedge takes up to 10 seconds
Thread.sleep(RANDOM.nextInt(10)*1000);
h.cut();
} catch (Exception e) {} // do something here
}
}
Now you need some construct to give him work; this is where the BlockingQueue comes in. We've already made sure the Environment can notify a Consumer<Integer> after a section has grown, so that's what we can use.
ExecutorService growingExecutor = Executors.newFixedThreadPool(10);
// so this is the queue
ExecutorService gardenerExecutor = Executors.newSingleThreadPool();
Gardener gardener = new Gardener();
for (int i = 0; i < 10; i++) {
Hedge section = new Hedge();
Consumer<Integer> cutSectionIfNeeded = i -> {
if (i > 8) { // size exceeded?
// have the gardener cut the section, ie adding item to queue
gardenerExecutor.submit(() -> gardener.cutHedge(section));
}
};
SectionGrower grower = new SectionGrower(section, cutSectionIfNeeded);
growingExecutor.submit(grower::run);
}
So I haven't actually tried this but it should work with some minor adjustments.
Note that I use the AtomicInteger in the hedge because it might grow and get cut "at the same time", because that happens in different threads.
The in following code Gardner waits for Segment to get to an arbitrary value of 9.
When Segment gets to 9, it notifies Gardner, and waits for Gardner to finish trimming:
import java.util.ArrayList;
import java.util.Collection;
public class Gardening {
public static void main(String[] args) {
Collection<Segment> segments = new ArrayList<>();
for(int i = 0; i < 2; i++) {
addSegment(segments);
}
Thread gardenerThread = new Thread(new Gardener(segments));
gardenerThread.start();
}
private static void addSegment(Collection<Segment> segments) {
Segment segment = new Segment();
Thread segmentThread = new Thread(segment);
segmentThread.start();
segments.add(segment);
}
}
class Gardener implements Runnable {
private Collection<Segment> segments;
private boolean isStop = false; //add stop flag
public Gardener(Collection<Segment> segmentsToLookAfter) {
segments = segmentsToLookAfter;
}
#Override
public void run() {
for (Segment segment : segments) {
follow(segment);
}
}
private void follow(Segment segment) {
new Thread(() -> {
Thread t = new Thread(segment);
t.start();
synchronized (segment) {
while(! isStop) {
try {
segment.wait(); //wait for segment
} catch (InterruptedException ex) { ex.printStackTrace();}
System.out.println("Trimming Segment " + segment.getId()+" size: "
+ segment.getCurrentSize() ); //add size to notes
segment.setCurrentSize(0); //trim size
segment.notify(); //notify so segment continues
}
}
}).start();
}
}
class Segment implements Runnable {
private int currentSize;
private boolean isStop = false; //add stop flag
private static int segmentIdCounter = 0;
private int segmentId = segmentIdCounter++; //add an id to identify thread
#Override
public void run() {
synchronized (this) {
while ( ! isStop ) {
if(Math.random() < 0.0000001) {
incrementSize();
}
if(getCurrentSize() >= 9) {
notify(); //notify so trimming starts
try {
wait(); //wait for gardener to finish
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
}
private synchronized void incrementSize() {
currentSize++;
System.out.println("Segment " + getId()+" size: "
+ getCurrentSize() );
}
public synchronized int getCurrentSize() { return currentSize; }
public synchronized void setCurrentSize(int newSize) {
currentSize = newSize;
}
public int getId() { return segmentId; }
}
The mutual waiting mechanizem can be implemented also with CountDownLatch.
Note that my experience with threads is limited. I hope other users comment and suggest improvements.

Multithreading Application won't run after JUnit Test

Im having problems with my Printer-Counter School Problem. Its supposed to be a multithreading application and runs fine so far. But when I running it the second or third time it wont work anymore.. No error message. Looks like Threads sleep forver or so. Also when I test it with a JUnit test it wont work. But sometimes it does... wich is already strange itself.
public class CounterPrinter {
public static void main(String[] args) throws InterruptedException {
if (args.length != 2) {
System.out.println("Usage: CounterPrinter <min> <max>");
System.exit(1);
}
Storage s = new Storage();
Printer d = new Printer(s, Integer.parseInt(args[1]));
Counter z = new Counter(s, Integer.parseInt(args[0]), Integer.parseInt(args[1]));
z.start();
d.start();
z.join();
d.join();
Thread.sleep(5000);
}
}
public class Printerextends Thread {
private Storage storage;
private Integer ende;
Printer(Storage s, Integer ende) {
this.storage = s;
this.ende = ende;
}
#Override
public void run() {
while (storage.hasValue()) {
try {
System.out.print(speicher.getValue(ende) + " ");
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Counter extends Thread {
private Storage speicher;
private int max, min;
Counter(Storages, int min, int max) {
this.storage = s;
this.max = max;
this.min = min;
}
#Override
public void run() {
for (int i = min; i <= max; i++) {
try {
storage.setValue(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Storage implements StorageIf {
private Integer wert;
private boolean hasValue = false;
#Override
public synchronized Integer getValue(Integer ende) throws InterruptedException {
if(wert.equals(ende)){
hasValue = false;
return wert;
}else {
while (!hasValue()) {
wait();
}
hasValue = false;
notifyAll();
return wert;
}
}
#Override
public synchronized void setValue(Integer wert) throws InterruptedException {
while (hasValue()){
wait();
}
hasValue = true;
this.wert = wert;
notifyAll();
}
#Override
public boolean hasValue() {
return hasValue;
}
}
Hope someone can spot a mistake I made :(
Thanks a lot!!!
The problem is that you conflate 2 states :
there is currently a value available
there will be no more values
Add an hasEnded() method to your Storage class, checking if the end value has been reached. Make sure to synchronize this method, as well as the hasValue() method. Synchronization needs to be done on both read and write access!
Then make Printer's while loop check hasEnded, rather than hasValue.
Finally : get rid of all the sleep() calls.
Your own answer, solving the problem with sleep, is not a real solution. A thread safe program does not depend on a computer's performance to function correctly.
z.start();
z.sleep(100);
d.start();
Putting a delay between starting the tow Threads solved the problem for me. My Computer was probably too fast down the road in Thread z before it even started Thread d. Thats why it hung itself up in 50% of the time.
Thanks to everyone tho :)

ShutDownHook in multi-threaded application

I have an application which in its main method spawns a hundred threads (let's say we simulate a hundred accounts). I am experimenting with it and I would like it to just print terminating when intterupted with Control-C.
I read you can do that with ShutDownHooks so I added the following in my main method:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Terminating");
}
});
However, when I run it nothing gets printed.
Could you please offer me some guidance as to where I am going wrong (all threads are declared in a for loop and start with invoking their start method)?
Regards,
George
EDIT: Please see below for the code:
Bank Class:
public class Bank {
private final double[] accounts;
public Bank(int n, double initialBalance) {
accounts = new double[n];
for (int i=0; i < accounts.length;i++) {
accounts[i] = initialBalance;
}
}
public double getTotalBalance() {
double sum = 0.0;
for (int i=0; i < accounts.length; i++) {
sum += accounts[i];
}
return sum;
}
public synchronized void transfer(int fa, int ta, double amt) throws InterruptedException{
System.out.print(Thread.currentThread());
if (accounts[fa] < amt){
wait();
}
accounts[ta] -= amt;
System.out.println("Transfer of amount: " + amt + " from: " + fa + " Transfer to: " + ta);
accounts[fa] += amt;
System.out.println("Total Balance: " + getTotalBalance());
notifyAll();
}
public int size() {
return accounts.length;
}
public double[] getAccounts(){
return accounts;
}
}
BankTest Class:
public class BankTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Bank b = new Bank(100,1000);
int i;
long timeStart = System.currentTimeMillis();
long j = System.currentTimeMillis();
for (i=0; i < b.size(); i++) {
TransferRunnable tr = new TransferRunnable(b, i, 1000,j);
Thread t = new Thread(tr);
t.start();
}
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Terminating");
}
});
}
}
TransferRunnable Class:
public class TransferRunnable implements Runnable {
private Bank b;
private int fromAccount;
private double maxAmount;
private final int DELAY = 40;
private long timeStart;
public TransferRunnable(Bank b, int from, double max, long timems) {
this.b = b;
fromAccount = from;
maxAmount = max;
timeStart = timems;
}
#Override
public void run() {
try {
while (true) {
int ta = (int) (b.size() * Math.random());
double amount = maxAmount * Math.random();
double[] acc = b.getAccounts();
b.transfer(fromAccount,ta,amount);
Thread.sleep((int) (DELAY*Math.random()));
}
}
catch (InterruptedException e) {
}
}
}
It gets printed when I run it. You could add System.out.flush(); to the end of the run() method though, this makes sure that the output is printed immediately.
as others have said, this should just work. What OS are you using? It might be that CTRL+C is killing the process completely rather than asking it to shutdown (eg SIGKILL vs SIGINT). Can you verify which signal you're sending the Java process?
Finally, as a last resort you could try the following bit of Java:
if (FileDescriptor.out.valid()) {
FileDescriptor.out.sync();
}
I suspect that this won't make any difference though!

Categories