简体   繁体   中英

synchronized in thread concepts of java

When I try to execute the piece of code, I am getting output like 12221121212121221212 . When I declare the method as synchronized , it should not allow the other thread to take over the control

package com.test;

public class TestProject extends Thread {

    public void run() {
        synchronized (this) {
            for (int i = 0; i < 10; i++) {
                System.out.print(getName());
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestProject myProject = new TestProject();
        TestProject myProject1 = new TestProject();
        myProject.setName("1");
        myProject1.setName("2");
        myProject.start();
        myProacject1.start();
    }
}

So, how do I alter the code to get a output of 11111111112222222222 or 22222222221111111111 in sequential format?

You are synchronizing on this , ie on the TestProject object. Since you have two separate objects, you have two separate locks. Consequently, both threads can enter the synchronized section irrespective of what the other thread is doing.

To synchronize across instances of TestProject you need a static lock:

public class TestProject extends Thread {

    private static final Object lock = new Object();

    public void run() {
        synchronized (lock) {
            ...

Java uses biased locking by default. This means a lock will favour the last thread to access a lock. If you consider that one thread can start, run and finish before the other even starts I would expect you get one thread running to completion before the other starts most of the time.

I have just noticed you lock outside the loop. This will guarantee you also run one thread to completion before the other starts.

This is how you can enforce fair alternation of threads.

public class TestProject implements Runnable {
    private final Lock lock;
    public TestProject(Lock lock) {
        this.lock = lock;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            lock.lock();
            try {
                System.out.print(Thread.currentThread().getName());
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String... ignored) {
        Lock lock = new ReentrantLock(true);
        new Thread(new TestProject(lock), "1").start();
        new Thread(new TestProject(lock), "2").start();
    }
}

can print

12121212121212121212

Note: if you make the lock non-fair you can get (change the true to false)

11111111112222222222

Note: if you want fair alternation between two tasks, it much simpler to use one thread and a loop.

public static void main(String... ignored) {
    for (int i = 0; i < 10; i++) {
        // task 1
        System.out.print("1");
        // task 2
        System.out.print("2");
    }
}

您还可以在myProject1上使用join方法,以便它等待另一个线程完成

these are the following method that can be used to achieve synchronization among the thread

1). use a static global lock and pass that object variable as argument to the synchronized block

2). use join()

3). create a instance for the Object class and pass that as an argument to the synchronized block like this Object myObject = TestProject.class now pass myObject to the synchronized block

using either of the above ways we can achieve synchronization

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM