首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步有什么问题?

同步有什么问题?
EN

Stack Overflow用户
提问于 2015-08-22 19:11:55
回答 4查看 205关注 0票数 0

代码的问题是,我的线程没有同步:在下面的示例中,我使用了线程将调用的同步打印方法,但是输出仍然显示,在访问print方法时线程是不同步的。见下面的输出。

主类

代码语言:javascript
复制
public class ExecutorTester {

    public static void main(String[] args) {

        PrinterRunnable pr = new PrinterRunnable();
        ExecutorService excutor = Executors.newFixedThreadPool(20);
        //ExecutorService excutor = Executors.newSingleThreadExecutor(); 
        excutor.submit(pr); 
        excutor.submit(pr); 
        excutor.submit(pr);
        excutor.submit(pr); 
        excutor.submit(pr); 
        excutor.submit(pr);
        excutor.submit(pr); 
        excutor.submit(pr); 
        excutor.submit(pr);

        excutor.shutdown();

        for(int i =0; i<5;i++)
            System.out.println("In Main Thread : "+i);
    }
}

线程类

代码语言:javascript
复制
public class PrinterRunnable implements Runnable {

    @Override
    public void run() {
        for(int i =0; i<5;i++){
            //System.out.println("In Thread class" +i);
            Printer p = new Printer();
            p.print(i);
        }
    }
}

其他类

代码语言:javascript
复制
public class Printer {

    public synchronized void print(int i){
        System.out.println("Entered Thread: "+Thread.currentThread().getId());
        System.out.println("In thread: "+Thread.currentThread().getId()+"count::"+i );
        System.out.println("Exit Thread: "+Thread.currentThread().getId());
    }
}

控制台输出(参见下面的线程13和11都被输入!)

代码语言:javascript
复制
Entered Thread: 13
Entered Thread: 11
In thread: 11count::0
Exit Thread: 11
Entered Thread: 11
In thread: 11count::1
Exit Thread: 11
In thread: 13count::0
Exit Thread: 13
Entered Thread: 13
In thread: 13count::1
Exit Thread: 13
........
........
........
EN

回答 4

Stack Overflow用户

发布于 2015-08-22 19:23:37

当关键字synchronized是方法签名的一部分时,如

代码语言:javascript
复制
public synchronized void print(int i)

然后,此同步引用调用该方法的实例。每次要打印某项内容时,都要创建一个新的Printer实例。

为了达到预期的效果,您必须对一个公共对象进行同步。例如,可以这样实现:

代码语言:javascript
复制
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorTester
{
    public static void main(String[] args)
    {
        PrinterRunnable pr = new PrinterRunnable(new Object());
        ExecutorService excutor = Executors.newFixedThreadPool(20);
        excutor.submit(pr);
        excutor.submit(pr);
        excutor.submit(pr);
        excutor.submit(pr);
        excutor.submit(pr);
        excutor.submit(pr);
        excutor.submit(pr);
        excutor.submit(pr);
        excutor.submit(pr);

        excutor.shutdown();

        for (int i = 0; i < 5; i++)
            System.out.println("In Main Thread : " + i);
    }
}

class PrinterRunnable implements Runnable
{
    private final Object monitor;

    PrinterRunnable(Object monitor)
    {
        this.monitor = monitor;
    }

    @Override
    public void run()
    {
        for (int i = 0; i < 5; i++)
        {
            // System.out.println("In Thread class" +i);
            Printer p = new Printer(monitor);
            p.print(i);
        }
    }
}

class Printer
{
    private final Object monitor;

    Printer(Object monitor)
    {
        this.monitor = monitor;
    }

    public void print(int i)
    {
        synchronized (monitor)
        {
            System.out.println("Entered Thread: " + 
                Thread.currentThread().getId());
            System.out.println("In thread: " + 
                Thread.currentThread().getId() + " count::" + i);
            System.out.println("Exit Thread: " + 
                Thread.currentThread().getId());
        }
    }
}

但当然,这是一个过于务实的草图。在实际的应用程序中,您应该仔细考虑要同步的对象。

票数 3
EN

Stack Overflow用户

发布于 2015-08-22 19:24:49

在这个地点:

代码语言:javascript
复制
@Override
public void run() {
    for(int i =0; i<5;i++){
        //System.out.println("In Thread class" +i);
        Printer p = new Printer();
        p.print(i);
    }
}

每个线程都在为每次迭代创建自己的打印机。同步的工作方式是阻止其他线程在同一个对象上执行同步方法,直到一个线程用它的同步方法完成为止。As:https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

票数 1
EN

Stack Overflow用户

发布于 2015-08-22 19:22:39

synchronized方法是对象的每个实例,在创建多个实例时没有争用。根据您的需求,您可以将方法更改为static或对类变量进行同步。

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

https://stackoverflow.com/questions/32159818

复制
相关文章

相似问题

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