Java 中的synchronized()/wait()/notifyAll() 是做什么的?

发布于 2024-11-27 19:04:08 字数 2070 浏览 1 评论 0原文

可能的重复:
Java 同步

我正在阅读《Beginning Android Games》一书。

它经常使用 synchronized() 但我不太明白它的作用。我已经很长时间没有使用Java了,我不确定我是否使用过多线程。

在 Canvas 示例中,它使用 synchronized(this)。然而,在 OpenGL ES 示例中,它创建一个名为 stateChanged 的对象,然后使用 synchronized(stateChanged)。当游戏状态发生变化时,它会调用 stateChanged.wait() ,然后调用 stateChanged.notifyAll();

一些代码:

    Object stateChanged = new Object();

    //The onPause() looks like this:
    public void onPause()
        {
            synchronized(stateChanged)
            {
                if(isFinishing())
                    state = GLGameState.Finished;
                else
                    state = GLGameState.Paused;

                while(true)
                {
                    try
                    {
                        stateChanged.wait();
                        break;
                    } catch(InterruptedException e)
                    {
                    }
                }
            }
        }
//The onDrawSurface looks like this:
public void onDrawFrame(GL10 gl)
    {
        GLGameState state = null;
        synchronized(stateChanged)
        {
            state = this.state;
        }

        if(state == GLGameState.Running)
        {

        }

        if(state == GLGameState.Paused)
        {
            synchronized(stateChanged)
            {
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            }
        }

        if(state == GLGameState.Finished)
        {
            synchronized(stateChanged)
            {
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            }
        }
    }

//the onResume() looks like this:
synchronized(stateChanged)
        {
            state = GLGameState.Running;
            startTime = System.nanoTime();
        }

Possible Duplicate:
Java Synchronization

I'm reading the book Beginning Android Games.

It uses synchronized() a lot but I don't really understand what it does. I haven't used Java in a long time and I'm not sure if I ever used multithreading.

In the Canvas examples it uses synchronized(this). However in the OpenGL ES example, it creates an Object called stateChanged and then uses synchronized(stateChanged). When the game state changes it calls stateChanged.wait() and then stateChanged.notifyAll();

Some code:

    Object stateChanged = new Object();

    //The onPause() looks like this:
    public void onPause()
        {
            synchronized(stateChanged)
            {
                if(isFinishing())
                    state = GLGameState.Finished;
                else
                    state = GLGameState.Paused;

                while(true)
                {
                    try
                    {
                        stateChanged.wait();
                        break;
                    } catch(InterruptedException e)
                    {
                    }
                }
            }
        }
//The onDrawSurface looks like this:
public void onDrawFrame(GL10 gl)
    {
        GLGameState state = null;
        synchronized(stateChanged)
        {
            state = this.state;
        }

        if(state == GLGameState.Running)
        {

        }

        if(state == GLGameState.Paused)
        {
            synchronized(stateChanged)
            {
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            }
        }

        if(state == GLGameState.Finished)
        {
            synchronized(stateChanged)
            {
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            }
        }
    }

//the onResume() looks like this:
synchronized(stateChanged)
        {
            state = GLGameState.Running;
            startTime = System.nanoTime();
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

无边思念无边月 2024-12-04 19:04:08

synchronized 关键字用于保持变量或方法的线程安全。如果将变量包装在同步块中,如下所示:

synchronized(myVar) {
    // Logic involing myVar
}

那么当同步块内的逻辑正在运行时,从另一个线程修改 myVar 值的任何尝试都将等待该块完成执行。它确保进入该块的值在该块的生命周期中都是相同的。

The synchronized keyword is used to keep variables or methods thread-safe. If you wrap a variable in a synchronized block like so:

synchronized(myVar) {
    // Logic involing myVar
}

Then any attempts to modify the value of myVar from another thread while the logic inside the synchronized block is running will wait until the block has finished execution. It ensures that the value going into the block will be the same through the lifecycle of that block.

醉生梦死 2024-12-04 19:04:08

这个 Java 教程 可能可以帮助您了解在对象确实如此。

当调用object.wait()时,它将释放该对象上持有的锁(当您说synchronized(object)时会发生这种情况),并冻结线程。然后,该线程将等待,直到由单独的线程调用 object.notify()object.notifyAll()。一旦发生其中一个调用,它将允许由于 object.wait() 而停止的任何线程继续。这意味着调用object.notify()object.notifyAll()的线程将冻结并将控制权传递给等待线程,这只是意味着这些等待线程现在能够继续,而之前却不能。

This Java Tutorial can probably help you understand what using synchronized on an object does.

When object.wait() is called it will release the lock held on that object (which happens when you say synchronized(object)), and freeze the thread. The thread then waits until object.notify() or object.notifyAll() is called by a separate thread. Once one of these calls occurs, it will allow any threads that were stopped due to object.wait() to continue. This does not mean that the thread that called object.notify() or object.notifyAll() will freeze and pass control to a waiting thread, it just means these waiting threads are now able to continue, whereas before they were not.

清眉祭 2024-12-04 19:04:08

像这样使用时:

private synchronized void someMehtod()

您会得到以下效果:

1. 首先,同一对象上的同步方法的两次调用不可能交错。当一个线程正在执行对象的同步方法时,调用同一对象的同步方法的所有其他线程都会阻塞(挂起执行),直到第一个线程完成该对象。

2. 其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立发生之前关系。这保证了对象状态的更改对所有线程都可见。

(取自此处

当您使用同步代码块:

private void someMethod() {
  // some actions...

  synchronized(this) {
    // code here has synchronized access
  }

  // more actions...
}

此处所述

When used like this:

private synchronized void someMehtod()

You get these effects:

1. First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

2. Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.

(Taken from here)

You get a similar effect when you use a synchronized block of code:

private void someMethod() {
  // some actions...

  synchronized(this) {
    // code here has synchronized access
  }

  // more actions...
}

As explained here

乜一 2024-12-04 19:04:08

Java(Android 的基础)可以在多个线程下运行,这些线程可以利用多个 CPU 核心。多线程意味着您可以让 Java 在同一时刻执行两个进程。如果您需要确保一次只能由一个线程操作一段代码或方法,则可以同步该代码块。

这是 Oracle 的官方 Java 解释

重要的是要知道使用同步会产生处理器/IO 成本,并且您只想在需要时使用它。研究哪些 Java 类/方法是线程安全的也很重要。例如,++ 递增运算符不能保证线程安全,而您可以轻松创建使用 += 1 递增值的同步代码块。

Java (which Android is based on) can run under multiple threads that can utilize multiple cpu cores. Multi-threading means that you can have Java doing two processes at the exact same moment. If you have a block of code or method that you need to ensure can only be operated by one thread at a time, you synchronize that block of code.

Here is the official Java explanation from Oracle

It's important to know that there is a processor/io costs involved with using synchronized and you only want to use it when you need it. It is also important to research what Java classes/methods are thread safe. For instance, the ++ increment operator is not guarateed to be thread safe, whereas you can easily create a block of synchronized code that increments a value using += 1.

方圜几里 2024-12-04 19:04:08

只有一个线程可以处于活动状态并且在给定对象同步的块内。
调用 wait stop 会放弃此权利并停用当前线程,直到有人调用 notification(all)()
然后,不活动的线程开始想要再次在同步块中运行,但与所有其他需要它的线程受到同等对待。只有以某种方式选择的一个(程序员不能影响也不依赖于哪一个)真正能够到达那里。

only one thread can be active and inside block synchronized by given object.
calling wait stops gives up this right and deactivates current thread until someone call notify(all)()
Then the inactive thread start wanting to run in the synchronized block again, but is treated equaly with all other threads that wants it. Only one somehow chosen (programmer cannot influence nor depend on which one) actualy gets there.

青衫负雪 2024-12-04 19:04:08

java中的synchronized关键字有两个用途。

第一个含义是所谓的临界区,即可以被一个线程同时访问的部分代码。您传递给 synchronized 的对象允许某种命名:如果一个代码在 synchronized(a) 中运行,它就无法访问 synchronized(a) 中的其他块) 但可以将代码块访问到 synchronized(b) 中。

另一个问题是线程间通信。线程可以等待,直到其他线程通知它。 wait 和notify 都必须写入synchronized 块中。

这是一个非常简短的描述。我建议您搜索一些有关多线程的教程并阅读它。

Synchronized keyword in java is used for 2 things.

First meaning is so called critical section, i.e. part of code that can be accessed by one thread simultaneously. The object you pass to synchronized allows some kind of naming: if one code is run in synchronized(a) it cannot access other block that is into synchronized(a) but can access block of code into synchronized(b).

Other issue is inter-thread communication. Thread can wait until other thread notifies it. Both wait and notify must be written into synchronized block.

It was a very short description. I'd suggest you to search for some tutorial about multithreading and read it.

〃安静 2024-12-04 19:04:08

关键字synchronized与等待和通知操作一起形成一个非阻塞条件监视器,用于协调多个线程的构造。

The keyword synchronized, together with the wait and notify operations form a nonblocking condition monitor, a construct useful for coordinating multiple threads.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文