Java 同步有什么问题吗

Java 同步有什么问题吗,java,multithreading,synchronized,Java,Multithreading,Synchronized,代码有什么问题,我的线程没有同步: 在下面的示例中,我有一个同步的print方法,线程将调用该方法,但输出仍然显示线程在访问print方法时没有同步。请参见下面的输出 主类 public class ExecutorTester { public static void main(String[] args) { PrinterRunnable pr = new PrinterRunnable(); ExecutorService excutor =

代码有什么问题,我的线程没有同步: 在下面的示例中,我有一个同步的print方法,线程将调用该方法,但输出仍然显示线程在访问print方法时没有同步。请参见下面的输出

主类

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);
    }
}
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);
        }
    }
}
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均已输入!!!)


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

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

当然,它们是同步的。每个人都在自己的监视器上,与自己的打印机对象相关。 因为您要创建5个不同的打印机对象,所以在不同的对象上执行“同步”,并且从不锁定执行过程

您应该创建一个对象并将其用于同步。 例如:

public class Printer {

    public void print(int i){
        syncrhonized(Printer.class) {
           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());
        }
    }
}

因为只有一个Printer.class对象,所以它们总是同步的。

当然,它们是同步的。每个人都在自己的监视器上,与自己的打印机对象相关。 因为您要创建5个不同的打印机对象,所以在不同的对象上执行“同步”,并且从不锁定执行过程

您应该创建一个对象并将其用于同步。 例如:

public class Printer {

    public void print(int i){
        syncrhonized(Printer.class) {
           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());
        }
    }
}

由于只有一个Printer.class对象,因此它们将始终同步。

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

public synchronized void print(int i)
然后,此同步引用调用此方法的实例。每次要打印内容时,您都要创建一个新的
打印机
实例

为了达到预期效果,必须在一个公共对象上进行同步。例如,这可以通过以下方式实现:

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());
        }
    }
}
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类执行器测试器
{
公共静态void main(字符串[]args)
{
PrinterRunnable pr=新的PrinterRunnable(新对象());
ExecutorService excutor=Executors.newFixedThreadPool(20);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行器关闭();
对于(int i=0;i<5;i++)
System.out.println(“主线程中:+i”);
}
}
类PrinterRunnable实现可运行
{
私有最终目标监视器;
PrinterRunnable(对象监视器)
{
this.monitor=监视器;
}
@凌驾
公开募捐
{
对于(int i=0;i<5;i++)
{
//System.out.println(“螺纹等级内”+i);
打印机p=新打印机(显示器);
p、 印刷品(一);
}
}
}
类打印机
{
私有最终目标监视器;
打印机(对象监视器)
{
this.monitor=监视器;
}
公开作废打印(int i)
{
同步(监视器)
{
System.out.println(“输入线程:”+
Thread.currentThread().getId());
System.out.println(“线程内:”+
Thread.currentThread().getId()+“计数::”+i);
System.out.println(“退出线程:”+
Thread.currentThread().getId());
}
}
}

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

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

public synchronized void print(int i)
然后,此同步引用调用此方法的实例。每次要打印内容时,您都要创建一个新的
打印机
实例

为了达到预期效果,必须在一个公共对象上进行同步。例如,这可以通过以下方式实现:

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());
        }
    }
}
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类执行器测试器
{
公共静态void main(字符串[]args)
{
PrinterRunnable pr=新的PrinterRunnable(新对象());
ExecutorService excutor=Executors.newFixedThreadPool(20);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行者提交(pr);
执行器关闭();
对于(int i=0;i<5;i++)
System.out.println(“主线程中:+i”);
}
}
类PrinterRunnable实现可运行
{
私有最终目标监视器;
PrinterRunnable(对象监视器)
{
this.monitor=监视器;
}
@凌驾
公开募捐
{
对于(int i=0;i<5;i++)
{
//System.out.println(“螺纹等级内”+i);
打印机p=新打印机(显示器);
p、 印刷品(一);
}
}
}
类打印机
{
私有最终目标监视器;
打印机(对象监视器)
{
this.monitor=监视器;
}
公开作废打印(int i)
{
同步(监视器)
{
System.out.println(“输入线程:”+
Thread.currentThread().getId());
System.out.println(“线程内:”+
Thread.currentThread().getId()+“计数::”+i);
System.out.println(“退出线程:”+
Thread.currentThread().getId());
}
}
}
但是