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

synchronized()/wait()/notifyAll()在Java中做什么?,java,android,multithreading,thread-safety,Java,Android,Multithreading,Thread Safety,可能重复: 我正在读《Android游戏入门》一书 它经常使用synchronized()。我已经很长时间没有使用Java了,我不确定我是否使用过多线程 在画布示例中,它使用了synchronized(this)。但是在OpenGL ES示例中,它创建了一个名为stateChanged的对象,然后使用synchronized(stateChanged)。当游戏状态改变时,它会调用stateChanged.wait(),然后调用stateChanged.notifyAll() 一些代码:

可能重复:

我正在读《Android游戏入门》一书

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

在画布示例中,它使用了
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();
        }

只有一个线程可以被激活,并且在给定对象的块内同步。 调用wait stops将放弃此权限并停用当前线程,直到有人调用notify(all)() 然后,非活动线程开始希望再次在同步块中运行,但会与所有其他需要它的线程同等对待。只有一个以某种方式选择的(程序员不能影响也不取决于哪一个)真正达到了目的。

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


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

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

synchronized(myVar) {
    // Logic involing myVar
}

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

java中的Synchronized关键字用于两件事

第一种意思是所谓的关键部分,即一个线程可以同时访问的代码部分。传递给
synchronized
的对象允许某种命名:如果一个代码在
synchronized(a)
中运行,它无法访问进入
synchronized(a)
的其他块,但可以访问进入
synchronized(b)
的代码块

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

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

这样使用时:

private synchronized void someMehtod()
您可以获得以下效果:

1。首先,同一对象上的两个同步方法调用不可能交错。当一个线程为一个对象执行同步方法时,调用同一对象块的同步方法的所有其他线程(暂停执行),直到第一个线程对该对象执行完毕

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

(摘自)

使用同步的代码块时,会得到类似的效果:

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

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

  // more actions...
}
如前所述,

可能有助于您了解在对象上使用同步的功能


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

关键字synchronized,与wait和notify操作一起构成一个用于协调多线程的结构。

Ok。wait()和notify()方法怎么样?他们是如何在线程中进行交互的。。。(我在原始问题中添加了一些代码)是的,我添加了@Joachim Sauver,这个问题不包括wait()/notify(),你只是添加了wait()/notify()-你应该试着第一次正确地组织问题,而不是现场构建问题。事实上,当我创建帖子时,我甚至没有在标题中指定synchronized(),但一些“版主”将标题改为“What does synchronized())你用Java做什么。。。好的,我们能不能停止讨论,因为它不能帮助我解决我的问题……正如@Charles Goodwin所怀疑的,您接受的Java教程答案在google搜索“Java synchronized”中也显示为第3项。这不是一个真正的支持问题,而是一个基本的java概念。在Google上首次点击某个主题,却被SO标记为重复,而没有提及声称的答案,这真是糟糕透了。至少有人给出了答案,对此我很感激。这是有道理的。。。因此,使用wait()停止将暂停应用程序的主线程,并使OpenGL ES停止。然后在OpenGL ES停止后,渲染器线程调用notifyAll(),使主线程完成暂停应用程序