在java的线程概念中同步

时间:2013-05-12 11:07:26

标签: java multithreading synchronized

当我尝试执行这段代码时,我得到的输出就像12221121212121221212一样。当我将方法声明为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();
    }
}

那么,如何更改代码以顺序格式获得 11111111112222222222 22222222221111111111 的输出?

4 个答案:

答案 0 :(得分:6)

您正在this上同步,即在TestProject对象上进行同步。由于您有两个单独的对象,因此您有两个单独的锁。因此,无论其他线程正在做什么,两个线程都可以进入synchronized部分。

要在TestProject的实例之间进行同步,您需要一个静态锁:

public class TestProject extends Thread {

    private static final Object lock = new Object();

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

答案 1 :(得分:1)

Java默认使用偏向锁定。这意味着锁将有利于最后一个线程访问锁。如果你认为一个线程可以在另一个线程开始之前启动,运行并完成,那么我希望你能让一个线程在大部分时间开始运行之前完成。

我刚注意到你在循环外锁定。这将保证您在另一个线程开始之前运行一个线程。

这是强制公平交替线程的方法。

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();
    }
}

可以打印

12121212121212121212

注意:如果您使锁定不公平,您可以获得(将true更改为false)

11111111112222222222

注意:如果你想在两个任务之间进行公平的交替,那么使用一个线程和一个循环要简单得多。

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");
    }
}

答案 2 :(得分:0)

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

答案 3 :(得分:0)

以下方法可用于实现线程之间的同步

1)。使用静态全局锁并将该对象变量作为参数传递给synchronized块

2)。使用join()

3)。为Object类创建一个实例,并将其作为参数传递给synchronized块,如此Object myObject = TestProject.class现在将myObject传递给synchronized块

使用上述任一方式我们都可以实现同步