synchronize concept in java doesn't work? - java

We have one hundred accounts in the bank and two clerks, implemented as threads, who transfer each 1000 times money from account with number accountNumberFrom to account accountNumberTo, using the synchronized method transferMoney. Since all accounts start with balance 0 and the money retrieved from one account is transferred to another, the balance should be zero after all the transactions. This is true most of the time, but not always. Although it occurs seldom, but sometimes the balance after the transactions is not equal to 0. What is wrong?
public class Clerk extends Thread {
private Bank bank;
public Clerk(String name, Bank bank) {
super(name);
this.bank=bank;
start();
}
public void run() {
for (long i=0; i<1000; i++) {
int accountNumberFrom = (int) (Math.random()*100);
int accountNumberTo = (int) (Math.random()*100);
float amount = (int) (Math.random()*1000) - 500;
bank.transferMoney(accountNumberFrom, amount);
bank.transferMoney(accountNumberTo, -amount);
}
}
}
and a class Bank
public class Bank {
Account[] account;
public Bank() {
account = new Account[100];
for (int i=0; i < account.length; i++)
account[i] = new Account();
}
public synchronized void transferMoney(int accountNumber, float amount) {
float oldBalance = account[accountNumber].getBalance();
float newBalance = oldBalance + amount;
account[accountNumber].setBalance(newBalance);
}
}
public class Banking {
public static void main (String[] args) {
Bank myBank = new Bank();
/**
* balance before transactions
*/
float sum=0;
for (int i=0; i<100; i++)
sum+=myBank.account[i].getBalance();
System.out.println("before: " + sum);
new Clerk ("Tom", myBank);
new Clerk ("Dick", myBank);
/**
* balance after transactions
*/
for (int i=0; i<100; i++)
sum+=myBank.account[i].getBalance();
System.out.println("after: " + sum);
}
}

One issue is that the synchronized transferMoney method only takes one account and so it's possible another thread could access the account balances after the transfer amount has been added to the "to" account but before it has been deducted from the "from" account. If all accounts start at zero, we could have this sequence of events:
Clerk Tom adds $100 to account 1.
Main thread totals account balances.
Clerk Tom deducts $100 from account 2.
At step 2 we see that the total of all accounts is $100 instead of zero.
So it's important that the transferMoney method update both accounts while holding the synchronized lock.
Another issue is that while the transferMoney is synchronized, the code that totals the account balances (step 2 above) is not. So even if you update both accounts in the transferMoney method, the sequence of events above can still happen because the main thread doesn't synchronize before executing step 2.
I would move the code that totals up the accounts to Bank and make it synchronized too. That will make both methods synchronized on the Bank instance and prevent the sequence of events that gives the wrong error.
A secondary issue is that in the main thread, you don't wait for the clerks to finish their transfers. Your code is performing all 1,000 transfers, but you just check the balances right after you start the clerk threads, so you may be looking at the balances after 0 transfers, or after all 1,000, or after 639 transfers, who knows. Doing the synchronization correctly will prevent you from seeing a non-zero total balance, but you should still wait for the clerks to finish. (Give it a try and if you can't figure it out, post a new question.)

In your example synchronized only block all thread call to myBank.transferMoney, but it doesn't ensure every threads done on main thread, you can update source code like this:
class Clerk extends Thread {
private Bank bank;
private volatile boolean done;
public Clerk(String name, Bank bank) {
super(name);
this.done = false;
this.bank=bank;
start();
}
public void run() {
for (long i=0; i<1000; i++) {
int accountNumberFrom = (int) (Math.random()*100);
int accountNumberTo = (int) (Math.random()*100);
float amount = (int) (Math.random()*1000) - 500;
bank.transferMoney(accountNumberFrom, amount);
bank.transferMoney(accountNumberTo, -amount);
}
this.done = true;
}
public boolean isDone() {
return done;
}
}
class Account {
protected float balance;
public float getBalance() {
return balance;
}
public void setBalance(float newBalance) {
this.balance = newBalance;
}
}
class Bank {
Account[] account;
public Bank() {
account = new Account[100];
for (int i=0; i < account.length; i++)
account[i] = new Account();
}
public synchronized void transferMoney(int accountNumber, float amount) {
float oldBalance = account[accountNumber].getBalance();
float newBalance = oldBalance + amount;
account[accountNumber].setBalance(newBalance);
}
}
public class Banking {
public static void main (String[] args) throws Exception {
for(int j = 0 ; j < 1000 ; ++j) {
Bank myBank = new Bank();
/**
* balance before transactions
*/
float sum=0;
for (int i=0; i<100; i++)
sum+=myBank.account[i].getBalance();
System.out.println("before: " + sum);
Clerk a = new Clerk ("Tom", myBank);
Clerk b = new Clerk ("Dick", myBank);
while(!a.isDone() || !b.isDone()) // wait util all thread done
Thread.sleep(1);
/**
* balance after transactions
*/
for (int i=0; i<100; i++)
sum+=myBank.account[i].getBalance();
System.out.println("after: " + sum);
}
}
}

Thanks a lot for the helpful answers. I modified my code and now it is working as it should:
public class Bank
{
Account[] account;
public Bank() {
account = new Account[100];
for (int i=0; i < account.length; i++)
account[i] = new Account();
}
public void transferMoney(int accountNumber, float amount) {
synchronized (account[accountNumber]) {
float oldBalance = account[accountNumber].getBalance();
float newBalance = oldBalance - amount;
account[accountNumber].setBalance(newBalance);
}
}
}
public class Account {
private float balance;
public void setBalance(float balance) {
this.balance=balance;
}
public float getBalance() {
return this.balance;
}
}
public class Clerk extends Thread {
private Bank bank;
public Clerk(String name, Bank bank) {
super(name);
this.bank=bank;
}
public void run() {
for (long i=0; i<100; i++) {
int accountNumberFrom = (int) (Math.random()*100);
int accountNumberTo = (int) (Math.random()*100);
float amount = (int) (Math.random()*1000);
bank.transferMoney(accountNumberFrom, -amount);
bank.transferMoney(accountNumberTo, amount);
}
}
}
public class Accountant extends Thread
{
Bank bank;
public Accountant(String name, Bank bank)
{
super(name);
this.bank=bank;
}
#Override public void run() {
getBalance();
}
public synchronized void getBalance() {
float sum=0;
System.out.println(Thread.currentThread().getName());
for (int i=0; i<100; i++)
sum+=bank.account[i].getBalance();
System.out.println("Bilanz: " + sum);
}
}
public class Banking {
public Banking() {
}
public static void main(String[] args) {
Bank myBank = new Bank();
Clerk tom = new Clerk ("Tom", myBank);
Clerk dick = new Clerk ("Dick", myBank);
Accountant harry = new Accountant("Harry", myBank);
tom.start();
dick.start();
try {
System.out.println("Current Thread: " + Thread.currentThread().getName());
tom.join();
dick.join();
}
catch(Exception x) {
System.out.println("Exception has " + "been caught" + x);
}
harry.start();
}
}

Related

Java Concurrency - Wrong Result When Using Synchronized Keyword

I am sorry for this basic question but I am so curious why I am not getting the correct result for the below code. I have a basic Account class which has 3 non-synchronized and 3 synchronized methods that do the same jobs. My expectation is to calculate the correct result when I use the synchronized keyword but when i run the application unfortunately I am getting a wrong error. What I am missing here? Thanks in advance guys!
Here's the Account class
public class Account {
private double balance;
public Account(int balance) {
this.balance = balance;
}
public boolean rawWithDraw(int amount) {
if (balance >= balance) {
balance = balance - amount;
return true;
}
return false;
}
public void rawDeposit(int amount) {
balance = balance + amount;
}
public double getRawBalance() {
return balance;
}
public boolean safeWithDraw(final int amount) {
synchronized (this){
if (balance >= amount) {
balance = balance - amount;
return true;
}
}
return false;
}
public void safeDeposit(final int amount) {
synchronized (this) {
balance = balance + amount;
}
}
public double getSafeBalance() {
synchronized (this) {
return balance;
}
}
}
and here's the main application
public class Main {
public static void main(String[] args) {
Account account1 = new Account(0);
Thread tA = new Thread(() -> account1.safeDeposit(70));
Thread tB = new Thread(() -> account1.safeDeposit(50));
tA.setName("thread-A");
tB.setName("thread-B");
tA.start();
tB.start();
System.out.println("The balance is : " + account1.getRawBalance());
}
}
And when I run the code, sometimes it prints 70, sometimes 0 and sometimes 120. What causing this?
You have not included getRawBalance() as a synchronized method, so it is allowed to run concurrently with either of the two synchronized methods. You can therefore see the result before either method executes, after both methods execute, or in between one and the other, giving four different possible outcomes.

non-synchronized method can access by other thread,,,,,,,

The lock on an object by one thread, no other thread can enter any of the synchronized methods in that class ,but i want to know about non-synchronized method can access by other thread,,,,,,,
class Account {
private int balance = 50;
public int getBalance() {
return balance;
}
public void withdraw(int amount) {
balance = balance - amount;
}
}
public class AccountDanger implements Runnable {
private Account acct = new Account();
public void run() {
for (int x = 0; x < 5; x++) {
this. d();
makeWithdrawal(10);
if (acct.getBalance() < 0) {
System.out.println("account is overdrawn!");
}
}
}
private synchronized void makeWithdrawal(int amt) {
if (acct.getBalance() >= amt) {
System.out.println(Thread.currentThread().getName()
+ " is going to withdraw"+amt);
try {
Thread.sleep(500);
// Thread.sleep(500);
} catch (InterruptedException ex) {
}
acct.withdraw(amt);
System.out.println(Thread.currentThread().getName()
+ " completes the withdrawal"+acct.getBalance());
} else {
System.out.println("Not enough in account for " + Thread.currentThread().getName()
+ " to withdraw " + acct.getBalance());
}
}
public static void main(String[] args) {
AccountDanger r = new AccountDanger();
Thread one = new Thread(r);
Thread two = new Thread(r);
one.setName("Fred");
two.setName("Lucy");
one.start();
two.start();
}
private void d() {
System.out.println("hhhhhhhhhhhhhhhhhhhhh"+Thread.currentThread().getName());
}
}
You have answer in your question itself :). If you are just looking for confirmation : YES.
No lock is required to access non-synchronized methods of an object.
If you want to know more about these concepts, visit Object Locks
Yes, the unsynchronized methods can be accessed/called by any Thread, that has/gets the reference to the same instance. Since you created a private Account instance and you didn't give this instance to any other class, in your example no other thread is able to access this special instance.

using semaphores for multithreading

Good Day!
I need to solve synchronization problem using semaphores. I've read many tutorials and I now know that I should use a release method and am acquire method, however, i don't know where to use them in the code. could you please help me or link me to a useful tutorial.
I have class Account:
public class Account {
protected double balance;
public synchronized void withdraw(double amount) {
this.balance = this.balance - amount;
}
public synchronized void deposit(double amount) {
this.balance = this.balance + amount;
}
}
I have two threads: Depositer:
public class Depositer extends Thread {
// deposits $10 a 10 million times
protected Account account;
public Depositer(Account a) {
account = a;
}
#Override
public void run() {
for(int i = 0; i < 10000000; i++) {
account.deposit(10);
}
}
}
And Withdrawer:
public class Withdrawer extends Thread {
// withdraws $10 a 10 million times
protected Account account;
public Withdrawer(Account a) {
account = a;
}
#Override
public void run() {
for(int i = 0; i < 1000; i++) {
account.withdraw(10);
}
}
}
here is the main:
public class AccountManager {
public static void main(String[] args) {
// TODO Auto-generated method stub
Account [] account = new Account[2];
Depositor [] deposit = new Depositor[2];
Withdrawer [] withdraw = new Withdrawer[2];
// The birth of 10 accounts
account[0] = new Account(1234,"Mike",1000);
account[1] = new Account(2345,"Adam",2000);
// The birth of 10 depositors
deposit[0] = new Depositor(account[0]);
deposit[1] = new Depositor(account[1]);
// The birth of 10 withdraws
withdraw[0] = new Withdrawer(account[0]);
withdraw[1] = new Withdrawer(account[1]);
for(int i=0; i<2; i++)
{
deposit[i].start();
withdraw[i].start();
}
for(int i=0; i<2; i++){
try {
deposit[i].join();
withdraw[i].join();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Using a semapahore for your example could look like this:
import java.util.concurrent.Semaphore;
public class Account {
private Semaphore semaphore = new Semaphore(1);
private double balance = 0;
public void withdraw(double amount){
deposit(amount * -1);
}
public void deposit(double amount){
semaphore.acquireUninterruptibly();
balance += amount;
semaphore.release();
}
}
This example is very similar semantically to the synchronized locking one as it sets up a single Semaphore per Account instance (similar to the single mutex available for locking on an object instance). It also waits uninterruptibly (i.e. forever) to acquire a permit, similar to the under the hood code that tries to acquire a lock on an object. If you didn't want to wait forever, you could change your impl to something like this:
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class Account {
private Semaphore semaphore = new Semaphore(1);
private double balance = 0;
public void withdraw(double amount){
deposit(amount * -1);
}
public void deposit(double amount){
try {
semaphore.tryAcquire(1, TimeUnit.SECONDS);
balance += amount;
semaphore.release();
}
catch (InterruptedException e) {
//Probably want to throw a more specific exception type here...
throw new RuntimeException("Timed out waiting for an account balance...");
}
}
}
In this example, you will only want up to 1 second to acquire a permit, and throw an exception if that does not happen.
I'm not sure if caught your problem properly, but I'll give it a shot.
Your Account class is already thread safe as you are using the 'synchronized' keyword for the withdraw and deposit methods. When a 'synchronized' method is called it locks on 'this', so any two 'synchronized' methods will never run at the same time for one instance of 'Account'.
But if you want to be able to read the balance of one account you should add an accessor that also is synchronized. In that case the balance could only be read by one thread at a time, this could be changed by using a 'ReentrantReadWriteLock'. Here is a code on how you would use it:
class Account {
private double balance;
private ReentrantReadWriteLock balanceLock = new ReentrantReadWriteLock();
public void withdraw(double amount) {
try {
balanceLock.writeLock().lock();
this.balance = this.balance - amount;
}
finally {
balanceLock.writeLock().unlock();
}
}
public void deposit(double amount) {
try {
balanceLock.writeLock().lock();
this.balance = this.balance + amount;
}
finally {
balanceLock.writeLock().unlock();
}
}
public double getBalance() {
try {
balanceLock.readLock().lock();
return this.balance;
}
finally {
balanceLock.readLock().unlock();
}
}
}
In this case several threads can be reading the balance at a time, but only one thread at a time could change the balance.

Avoid Deadlock example

I am wondering what are the alternative ways to avoid deadlock in the following example. The following example is a typical bank account transferring deadlock problem. What are some of the better approaches to solve it in practice ?
class Account {
double balance;
int id;
public Account(int id, double balance){
this.balance = balance;
this.id = id;
}
void withdraw(double amount){
balance -= amount;
}
void deposit(double amount){
balance += amount;
}
}
class Main{
public static void main(String [] args){
final Account a = new Account(1,1000);
final Account b = new Account(2,300);
Thread a = new Thread(){
public void run(){
transfer(a,b,200);
}
};
Thread b = new Thread(){
public void run(){
transfer(b,a,300);
}
};
a.start();
b.start();
}
public static void transfer(Account from, Account to, double amount){
synchronized(from){
synchronized(to){
from.withdraw(amount);
to.deposit(amount);
}
}
}
}
I am wondering if the deadlock issue will be solved if I separate the nested lock out in my transfer method like the following
synchronized(from){
from.withdraw(amount);
}
synchronized(to){
to.deposit(amount);
}
Sort the accounts. The dead lock is from the ordering of the accounts (a,b vs b,a).
So try:
public static void transfer(Account from, Account to, double amount){
Account first = from;
Account second = to;
if (first.compareTo(second) < 0) {
// Swap them
first = to;
second = from;
}
synchronized(first){
synchronized(second){
from.withdraw(amount);
to.deposit(amount);
}
}
}
In addition to the solution of lock ordered you can also avoid the deadlock by synchronizing on a private static final lock object before performing any account transfers.
class Account{
double balance;
int id;
private static final Object lock = new Object();
....
public static void transfer(Account from, Account to, double amount){
synchronized(lock)
{
from.withdraw(amount);
to.deposit(amount);
}
}
This solution has the problem that a private static lock restricts the system to performing transfers "sequentially".
Another one can be if each Account has a ReentrantLock:
private final Lock lock = new ReentrantLock();
public static void transfer(Account from, Account to, double amount)
{
while(true)
{
if(from.lock.tryLock()){
try {
if (to.lock.tryLock()){
try{
from.withdraw(amount);
to.deposit(amount);
break;
}
finally {
to.lock.unlock();
}
}
}
finally {
from.lock.unlock();
}
int n = number.nextInt(1000);
int TIME = 1000 + n; // 1 second + random delay to prevent livelock
Thread.sleep(TIME);
}
}
Deadlock does not occur in this approach because those locks will never be held indefinitely. If the current object's lock is acquired but the second lock is unavailable, the first lock is released and the thread sleeps for some specified amount of time before attempting to reacquire the lock.
This is a classic question. I see two possible solutions:
To sort accounts and synchronize at account which has an id lower than another one.
This method mentioned in the bible of concurrency Java Concurrency in Practice in chapter 10. In this book authors use system hash code to distinguish the accounts. See java.lang.System#identityHashCode.
The second solution is mentioned by you - yes you can avoid nested synchronized blocks and your code will not lead to deadlock. But in that case the processing might have some problems because if you withdraw money from the first account the second account may be locked for any significant time and probably you will need to put money back to the first account. That's not good and because that nested synchronization and the lock of two accounts is better and more commonly used solution.
You can also create separate lock for each Account (in Account class) and then before doing transaction acquire both locks. Take a look:
private boolean acquireLocks(Account anotherAccount) {
boolean fromAccountLock = false;
boolean toAccountLock = false;
try {
fromAccountLock = getLock().tryLock();
toAccountLock = anotherAccount.getLock().tryLock();
} finally {
if (!(fromAccountLock && toAccountLock)) {
if (fromAccountLock) {
getLock().unlock();
}
if (toAccountLock) {
anotherAccount.getLock().unlock();
}
}
}
return fromAccountLock && toAccountLock;
}
After get two locks you can do transfer without worrying about safe.
public static void transfer(Acc from, Acc to, double amount) {
if (from.acquireLocks(to)) {
try {
from.withdraw(amount);
to.deposit(amount);
} finally {
from.getLock().unlock();
to.getLock().unlock();
}
} else {
System.out.println(threadName + " cant get Lock, try again!");
// sleep here for random amount of time and try do it again
transfer(from, to, amount);
}
}
Here is the solution for the problem stated.
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class FixDeadLock1 {
private class Account {
private final Lock lock = new ReentrantLock();
#SuppressWarnings("unused")
double balance;
#SuppressWarnings("unused")
int id;
public Account(int id, double balance) {
this.balance = balance;
this.id = id;
}
void withdraw(double amount) {
this.balance -= amount;
}
void deposit(double amount) {
balance += amount;
}
}
private class Transfer {
void transfer(Account fromAccount, Account toAccount, double amount) {
/*
* synchronized (fromAccount) { synchronized (toAccount) {
* fromAccount.withdraw(amount); toAccount.deposit(amount); } }
*/
if (impendingTransaction(fromAccount, toAccount)) {
try {
System.out.format("Transaction Begins from:%d to:%d\n",
fromAccount.id, toAccount.id);
fromAccount.withdraw(amount);
toAccount.deposit(amount);
} finally {
fromAccount.lock.unlock();
toAccount.lock.unlock();
}
} else {
System.out.println("Unable to begin transaction");
}
}
boolean impendingTransaction(Account fromAccount, Account toAccount) {
Boolean fromAccountLock = false;
Boolean toAccountLock = false;
try {
fromAccountLock = fromAccount.lock.tryLock();
toAccountLock = toAccount.lock.tryLock();
} finally {
if (!(fromAccountLock && toAccountLock)) {
if (fromAccountLock) {
fromAccount.lock.unlock();
}
if (toAccountLock) {
toAccount.lock.unlock();
}
}
}
return fromAccountLock && toAccountLock;
}
}
private class WrapperTransfer implements Runnable {
private Account fromAccount;
private Account toAccount;
private double amount;
public WrapperTransfer(Account fromAccount,Account toAccount,double amount){
this.fromAccount = fromAccount;
this.toAccount = toAccount;
this.amount = amount;
}
public void run(){
Random random = new Random();
try {
int n = random.nextInt(1000);
int TIME = 1000 + n; // 1 second + random delay to prevent livelock
Thread.sleep(TIME);
} catch (InterruptedException e) {}
new Transfer().transfer(fromAccount, toAccount, amount);
}
}
public void initiateDeadLockTransfer() {
Account from = new Account(1, 1000);
Account to = new Account(2, 300);
new Thread(new WrapperTransfer(from,to,200)).start();
new Thread(new WrapperTransfer(to,from,300)).start();
}
public static void main(String[] args) {
new FixDeadLock1().initiateDeadLockTransfer();
}
}
There are three requirements you must satisfy:
Consistently reduce the contents of one account by the specified amount.
Consistently increase the contents of the other account by the specified amount.
If one of the above is successful, the other must also be successful.
You can achieve 1. and 2. by using Atomics, but you will have to use something other that double as there is no AtomicDouble. AtomicLong would probably be your best bet.
So you're left with your third requirement - if one succeeds the other must succeed. There is a simple technique that works superbly with atomics and that is using the getAndAdd methods.
class Account {
AtomicLong balance = new AtomicLong ();
}
...
Long oldDebtor = null;
Long oldCreditor = null;
try {
// Increase one.
oldDebtor = debtor.balance.getAndAdd(value);
// Decrease the other.
oldCreditor = creditor.balance.gtAndAdd(-value);
} catch (Exception e) {
// Most likely (but still incredibly unlikely) InterruptedException but theoretically anything.
// Roll back
if ( oldDebtor != null ) {
debtor.getAndAdd(-value);
}
if ( oldCreditor != null ) {
creditor.getAndAdd(value);
}
// Re-throw after cleanup.
throw (e);
}

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