简体   繁体   English

在Java线程概念中同步

[英]synchronized in thread concepts of java

When I try to execute the piece of code, I am getting output like 12221121212121221212 . 当我尝试执行一段代码时,我得到的输出是12221121212121221212 When I declare the method as synchronized , it should not allow the other thread to take over the control 当我将方法声明为synchronized ,它不应允许其他线程接管控件

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? 那么,如何更改代码以获得顺序格式的1111111111222222222222222222221111111111111的输出?

You are synchronizing on this , ie on the TestProject object. 您正在this上同步,即在TestProject对象上同步。 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. 因此,两个线程都可以进入synchronized部分,而不管另一个线程在做什么。

To synchronize across instances of TestProject you need a static lock: 要跨TestProject实例同步,您需要一个静态锁:

public class TestProject extends Thread {

    private static final Object lock = new Object();

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

Java uses biased locking by default. Java默认情况下使用偏向锁定。 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) 注意:如果您将锁设为不公平,则可以获得(将true更改为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). 1)。 use a static global lock and pass that object variable as argument to the synchronized block 使用静态全局锁并将该对象变量作为参数传递给同步块

2). 2)。 use join() 使用join()

3). 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 为Object类创建一个实例,并将其作为参数传递给同步块,例如Object myObject = TestProject.class现在将myObject传递给同步块

using either of the above ways we can achieve synchronization 使用以上两种方法之一,我们可以实现同步

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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