简体   繁体   English

编写同步方法java

[英]writing synchronized method java

I can not understand why no thread never enters into the method wait 我不明白为什么没有线程永远不会进入方法等待

public class File {

    private boolean writing = false;

    public synchronized void write()
    { 
        String name = Thread.currentThread().getName();
        while(this.writing == true){
            System.out.println(name +" wait "); 
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.writing=true;
        System.out.println(name +" writing ");
        try{
            Thread.sleep((int)(Math.random()*3000));
        } catch( InterruptedException e){
            e.printStackTrace();
        }
        this.writing=false;
        System.out.println(name +" writing end ");
        this.notifyAll();
    }   
}

public class M_thread extends Thread{
    File file;

    public M_thread(String name,File f){
        super(name);
        this.file=f;
    }

    public void run(){
        while(true){
            file.write();
        }
    }   
}


public class Main {

    public static void main(String[] args) {
        File file=new File();
        new M_thread("t1",file).start();
        new M_thread("t2",file).start();
        new M_thread("t3",file).start();    
    }
}

In my code as I can prevent the problem of starvation caused by the simulation method of writing with sleep ? 在我的代码中,我可以防止用睡眠书写的模拟方法引起的饥饿问题? Because if a thread is put to sleep for a long time always will never write than one that you put to sleep for a short time 因为如果一个线程长时间处于休眠状态,则永远不会比您短时间处于休眠状态的线程写。

I can not understand why no thread never enters into the method wait Well, this is relatively easy to describe: I can not understand why no thread never enters into the method wait嗯,这相对容易描述:

public synchronized void write() {
    // ...
}

This is the same as: 这与:

public void write() {
    synchronized(this) {
        // ...
    }
}

That means, that only one thread with the lock this can enter this block. 这意味着,与锁只有一个线程this也能进入这个块。 Since you're using the same instance of File : 由于您使用的是File的相同实例:

File file=new File();
new M_thread("t1",file).start();
new M_thread("t2",file).start();
new M_thread("t3",file).start(); 

.. every Thread has the same object reference on this . ..每个线程对同一对象的引用this Therefore, if one thread enters the method write , then the other thread have to wait until this one thread releases the lock on this . 因此,如果一个线程进入方法write ,则另一个线程必须等待,直到该一个线程释放this的锁。 And since the default value of writing is false (and the value will be reset to false if a thread leaves the write method), the loop while(this.writing == true) will never be entered. 而且,由于默认值writingfalse (和值将被重置为false ,如果一个线程离开write方法),环while(this.writing == true)将永远不会被输入。

Your understanding of synchronization is a bit off, it is simpler than you think. 您对同步的理解有些偏离,它比您想象的要简单。

None of your threads will be in write() at the same time because it is synchronized . 您的所有线程都不会同时处于write()中,因为它是synchronized So, none of the extraneous wait/notify logic you have is necessary. 因此,您不需要任何多余的等待/通知逻辑。 this.writing will never be true at the start of write() because you set it to false just before leaving every write() , and since write() is synchronized , no threads are "jumping in" to the middle of it anyways. this.writingwrite()开始时永远不会为真,因为您在离开每个write()之前将其设置为false,并且由于write()synchronized ,因此无论如何都不会有线程“跳入”它的中间。 That is, no thread will ever execute write() during that period that this.writing is true. 也就是说,在this.writing为true的时间段内,没有线程会执行write()

You can get rid of all of that logic. 您可以摆脱所有这些逻辑。 This is sufficient, as synchronized already does this work for you: 这已经足够了,因为synchronized已经为您完成了这项工作:

public synchronized void write()
{ 
    String name = Thread.currentThread().getName();
    System.out.println(name +" writing ");
    Thread.sleep((int)(Math.random()*3000)); 
    System.out.println(name +" writing end ");
}

Just declaring write() as synchronized will already cause other threads that call write() to wait their turn. write()声明为已synchronized将导致其他调用write()线程轮流等待。

Note that your sleep() call will not throw InterruptedException in your example, as you never call interrupt() ( interruptions do not come out of nowhere ). 请注意,您的sleep()调用不会在您的示例中引发InterruptedException ,因为您从不会调用interrupt()中断不会从任何地方发出来 )。 I have left out that exception handler for simplicity. 为了简化起见,我省略了该异常处理程序。 That said, if you are constructing code to be used in other situations, it's never a bad idea to make it interrupt() -safe, since you never know how your code will end up being used in the future (somebody may use it in a context where they expect interrupt() to work). 就是说,如果您要构造要在其他情况下使用的代码,则将其设置为interrupt() safe绝不是一个坏主意,因为您永远不知道自己的代码将来会如何使用(有人可能会在将来使用它)。他们期望interrupt()工作的上下文)。

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

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