Home > Enterprise >  Java thread synchronized for multi-threaded ticket selling example
Java thread synchronized for multi-threaded ticket selling example

Time:10-12

I want to write a multi-threaded ticket selling example, but the output looks like only one thread is working

public class test2 {
public static void main(String[] args) {
    per per = new per();
    Thread t1 = new Thread(per);
    Thread t2 = new Thread(per);
    Thread t3 = new Thread(per);
    t1.start();
    t2.start();
    t3.start();
}

}
class per implements Runnable{
int ticket = 10;
final String a = "";
@Override
public void run() {
    while (true) {
        synchronized(a) {
            if (ticket>0) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() " " ticket);
                ticket--;
            }
        }
    }
}
}

As a result, only the thread has sold all the tickets. The result is as follows:

Thread-1 ticket 9
Thread-1 ticket 8
Thread-1 ticket 7
Thread-1 ticket 6
Thread-1 ticket 5
Thread-1 ticket 4
Thread-1 ticket 3
Thread-1 ticket 2
Thread-1 ticket 1
Thread-1 ticket 0

CodePudding user response:

Your problem is where you have placed your call to syncronized() in relation to where you have your call to sleep(). What is likely happening is that because your first thread gets the mutex first and then has it most of the time, only giving it up for the briefest moments, the thread scheduler never decides to give the lock to a different thread. If you sleep outside of the sync block, which is a much better simulation of what threads would be doing in real life, then your code acts the way you're expecting. This code:

public class Test {
    public static void main(String[] args) {
        per per = new per();
        Thread t1 = new Thread(Per);
        Thread t2 = new Thread(Per);
        Thread t3 = new Thread(Per);
        t1.start();
        t2.start();
        t3.start();
    }
}

class Per implements Runnable{
    int ticket = 10;
    final String a = "";
    @Override
    public void run() {
        while (true) {
            synchronized(a) {
                if (ticket>0) {
                    System.out.println(Thread.currentThread().getName() " " ticket);
                    ticket--;
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

Give me this result:

Thread-0 10
Thread-2 9
Thread-1 8
Thread-0 7
Thread-2 6
Thread-1 5
Thread-1 4
Thread-0 3
Thread-2 2
Thread-2 1

CodePudding user response:

Nothing in this code would force other threads to be scheduled before ticket reaches 0 on the first thread. While it is possible that other threads could be scheduled between each iteration, it isn’t required, and as an optimization the OS might choose to keep the first thread running instead of having to do a context switch to schedule one of the others.

CodePudding user response:

every thread should use it's own per object,like below:

    public static void main(String[] args) {
//        per per = new per();
        Thread t1 = new Thread(new per());
        Thread t2 = new Thread(new per());
        Thread t3 = new Thread(new per());
        t1.start();
        t2.start();
        t3.start();
    }

enter image description here

@CryptoFool

There is some confusion,if I increase the number of tickets and reduce the sleep time. The program seems to be working properly.

public class TestThread {

    public static void main(String[] args) {
        per per = new per();
        Thread t1 = new Thread(per);
        Thread t2 = new Thread(per);
        Thread t3 = new Thread(per);
        t1.start();
        t2.start();
        t3.start();
    }

}
class per implements Runnable{
    int ticket = 10000;
    final String a = "";
    @Override
    public void run() {
        while (true) {
            synchronized(a) {
                if (ticket>0) {
                    try {
                        Thread.sleep(1  );
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() " " ticket);
                    ticket--;
                }
            }

        }
    }
}

and I got the below result

...other output...
Thread-0 9965
Thread-0 9964
Thread-0 9963
Thread-0 9962
Thread-0 9961
Thread-1 9960
Thread-1 9959
Thread-1 9958
Thread-1 9957
Thread-1 9956
Thread-1 9955
Thread-1 9954
Thread-1 9953
Thread-1 9952
Thread-1 9951
Thread-1 9950
Thread-1 9949
Thread-1 9948
Thread-1 9947
Thread-1 9946
Thread-1 9945
Thread-1 9944
Thread-1 9943
Thread-1 9942
Thread-1 9941
Thread-1 9940
Thread-1 9939
Thread-1 9938
Thread-1 9937
Thread-1 9936
Thread-1 9935
Thread-1 9934
Thread-1 9933
Thread-1 9932
Thread-1 9931
Thread-1 9930
Thread-1 9929
Thread-1 9928
Thread-1 9927
Thread-1 9926
Thread-1 9925
Thread-1 9924
Thread-1 9923
Thread-1 9922
Thread-1 9921
Thread-1 9920
Thread-1 9919
Thread-1 9918
Thread-1 9917
Thread-1 9916
Thread-1 9915
Thread-1 9914
Thread-1 9913
Thread-1 9912
Thread-1 9911
Thread-1 9910
Thread-1 9909
Thread-1 9908
Thread-1 9907
Thread-1 9906
Thread-1 9905
Thread-1 9904
Thread-1 9903
Thread-1 9902
Thread-1 9901
Thread-1 9900
Thread-1 9899
Thread-1 9898
Thread-1 9897
Thread-2 9896
Thread-2 9895
Thread-2 9894
Thread-2 9893
Thread-2 9892
Thread-2 9891
...other output...
  •  Tags:  
  • java
  • Related