首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步run()方法

同步run()方法
EN

Stack Overflow用户
提问于 2013-10-30 16:35:09
回答 2查看 8.4K关注 0票数 0

众所周知,只有一个同步方法可以同时运行。所以我的问题是,如果我声明run()方法是同步的,然后运行多线程,那么其他线程是否有可能运行run()方法?如下所示:

代码语言:javascript
复制
public Test extends Thread
{
    public synchronized void run()
       {...do something}

}
Test thread1 = new Test();
Test thread2 = new Test();
thread1.start();
thread2.start();

thread2可以运行还是thread2会等待thread1退出run()方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-30 17:32:09

实例方法上的synchronized关键字防止在同一个实例上调用该方法的并发调用。

尝试下面的(1)

代码语言:javascript
复制
class SynchTest {
    public static void main(String[] args) {
        // Note that we create a new Task each time.
        new Thread(new Task()).start();
        new Thread(new Task()).start();
        new Thread(new Task()).start();
    }

    static class Task implements Runnable {
        long start;

        Task() {
            this.start = System.currentTimeMillis();
        }

        @Override
        public synchronized void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignored) {
            }
            System.out.println(System.currentTimeMillis() - start);
        }
    }
}

它将输出如下内容:

代码语言:javascript
复制
1000
1001
1001

换句话说,创建每个任务所需的时间大约是1秒,这意味着所有任务都可以同时运行。

现在尝试下面的(2)

代码语言:javascript
复制
class SynchTest {
    public static void main(String[] args) {
        // Now we pass the same instance each time.
        Task t = new Task();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
    }

    static class Task implements Runnable {
        long start;

        Task() {
            this.start = System.currentTimeMillis();
        }

        @Override
        public synchronized void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignored) {
            }
            System.out.println(System.currentTimeMillis() - start);
        }
    }
}

将同一个实例传递给所有3个线程意味着线程将尝试在同一个实例上调用run。这输出如下所示:

代码语言:javascript
复制
1001
2001
3001

换句话说,每个任务都是为了等待上一个任务。

如果您确实希望为每个对象指定所有的synchronize,则可以指定您自己的监视器对象(3)

代码语言:javascript
复制
class SynchTest {
    public static void main(String[] args) {
        new Thread(new Task()).start();
        new Thread(new Task()).start();
        new Thread(new Task()).start();
    }

    static class Task implements Runnable {
        long start;

        Task() {
            this.start = System.currentTimeMillis();
        }

        static final Object STATIC_MONITOR = new Object();

        @Override
        public void run() {
            synchronized (STATIC_MONITOR) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ignored) {
                }
                System.out.println(System.currentTimeMillis() - start);
            }
        }
    }
}

它的输出与示例2相同,尽管我们每次都创建一个新任务。

另见:应该同步运行方法吗?为什么或者为什么不?

票数 4
EN

Stack Overflow用户

发布于 2019-01-05 03:54:31

创建两个Test实例以及每个线程运行两个线程,因此其他线程不可能运行run()方法。只有当两个线程使用相同的实例运行时,如下所示:

代码语言:javascript
复制
class CustomTask implements Runnable {
    private int number;
    public synchronized void run() {
        while(!Thread.currentThread().isInterrupted()){
            System.out.println(Thread.currentThread().getName() + ": " + number);
            Thread.yield();
            ++number;
        }   
    }   
}

public class ThreadTest {
    public static void main(String... args) throws Exception {
        CustomTask ct = new CustomTask();
        ExecutorService exec = Executors.newCachedThreadPool();
        for(int i = 0; i < 2; i++){
            exec.execute(ct);
        }   
        TimeUnit.MILLISECONDS.sleep(1);
        exec.shutdownNow();    
    }   
}

对于run方法,需要一个同步关键字。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19688666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档