Java,为什么需要使用同步?而不是使用单个线程?
在阅读有关Java synchronized的文章时,我只是想知道,如果处理应该是同步的,为什么不创建一个线程(而不是主线程)并逐个处理,而不是创建多个线程呢 因为,通过“synchronized”,除了单个正在运行的线程之外,所有其他线程都将等待。看起来只有一个线程在运行 请告诉我我错过了什么 如果您能给出一些用例,我将不胜感激 我读了一个例子,关于从两个ATM设备访问银行账户的例子。但这让我更加困惑,我认为封锁应该由数据库端完成。我认为“同步”在多个EC2实例之间不起作用Java,为什么需要使用同步?而不是使用单个线程?,java,Java,在阅读有关Java synchronized的文章时,我只是想知道,如果处理应该是同步的,为什么不创建一个线程(而不是主线程)并逐个处理,而不是创建多个线程呢 因为,通过“synchronized”,除了单个正在运行的线程之外,所有其他线程都将等待。看起来只有一个线程在运行 请告诉我我错过了什么 如果您能给出一些用例,我将不胜感激 我读了一个例子,关于从两个ATM设备访问银行账户的例子。但这让我更加困惑,我认为封锁应该由数据库端完成。我认为“同步”在多个EC2实例之间不起作用 如果我的想法是错误
如果我的想法是错误的,请纠正我。如果使用多个线程运行的所有代码都在一个同步块中,那么与使用单个线程相比,它确实没有什么区别
然而,一般来说,您的代码包含可以在多个线程上并行运行的部分和不能并行运行的部分。后者需要同步,但前者不需要。通过使用多个线程,您可以加快可并行位的速度。如果使用多个线程运行的所有代码都在一个同步块内,那么与使用单个线程相比,它确实没有什么区别
然而,一般来说,您的代码包含可以在多个线程上并行运行的部分和不能并行运行的部分。后者需要同步,但前者不需要。通过使用多个线程,您可以加快可并行位的速度。您可以拥有一个线程并逐个处理,这是可以做到的,但是这样做会产生大量的开销,并且不会消除同步的需要 您所处的环境是从多个线程开始,例如,您有许多同时进行的web会话。您希望在单个线程中完成部分处理,比如用一些新数据更新一些公共结构。您需要将新数据传递到单个线程-如何将其传递到那里?您必须使用某种消息队列或等效的东西,让单线程从消息队列中拾取请求,并且无论如何都必须同步,此外还有管理队列的开销,以及需要从单线程异步获取回复的问题。你又回到原点了 这种技术用于需要进行大量处理且不想长时间阻塞主线程的情况
总而言之:拥有一个线程并不能消除同步的需要。您可以拥有一个线程并逐个处理,这是可以做到的,但是这样做会产生相当大的开销,并且不会消除同步的需要 您所处的环境是从多个线程开始,例如,您有许多同时进行的web会话。您希望在单个线程中完成部分处理,比如用一些新数据更新一些公共结构。您需要将新数据传递到单个线程-如何将其传递到那里?您必须使用某种消息队列或等效的东西,让单线程从消息队列中拾取请求,并且无论如何都必须同步,此外还有管理队列的开销,以及需要从单线程异步获取回复的问题。你又回到原点了 这种技术用于需要进行大量处理且不想长时间阻塞主线程的情况
摘要:有一个线程不能消除同步的需要。
让我们考虑下面的用例:
您的应用程序是一个internet浏览器游戏。每个玩家都有一个分数,可以点击一个按钮。每次玩家点击按钮,他们的得分就会增加,对手的得分就会减少。第一个达到10胜的玩家 <> P>根据游戏的性质,并选择一个唯一的赢家,你必须考虑两个计数器增加和检查赢家原子。 你将让每个玩家在自己的线程上发送clickEvents,每个事件都将转化为所有者计数器的增加、计数器是否达到10以及对手计数器的减少 通过同步处理修改计数器的方法很容易做到这一点:每个并发线程都将尝试获取锁,当它们获取锁时,它们将执行代码并最终释放锁 锁定机制非常轻量级,只需要一个关键字的代码 如果我们按照您的建议实现另一个线程来处理执行,那么我们必须实现整个线程管理逻辑m ore代码,为了初始化该线程更多的资源,即使如此,为了保证事件处理的公平性,您仍然需要一种方法让您的客户机线程将事件传递给您的执行线程。我看到这样做的唯一方法是实现BlockingQueue,它也是同步的,以防止在尝试从另外两个线程添加元素时自然发生的争用情况我实在看不出有什么方法可以解决这个非常简单的用例,而不需要同步或实现基本上相同的锁定算法 >考虑下面的用例: 您的应用程序是一个internet浏览器游戏。每个玩家都有一个分数,可以点击一个按钮。每次玩家点击按钮,他们的得分就会增加,对手的得分就会减少。第一个达到10胜的玩家 <> P>根据游戏的性质,并选择一个唯一的赢家,你必须考虑两个计数器增加和检查赢家原子。 你将让每个玩家在自己的线程上发送clickEvents,每个事件都将转化为所有者计数器的增加、计数器是否达到10以及对手计数器的减少 通过同步处理修改计数器的方法很容易做到这一点:每个并发线程都将尝试获取锁,当它们获取锁时,它们将执行代码并最终释放锁 锁定机制非常轻量级,只需要一个关键字的代码 如果我们按照你的建议实现另一个线程来处理执行,我们就必须实现整个线程管理逻辑更多的代码,初始化该线程更多的资源,即使如此,也要保证事件处理的公平性,您仍然需要客户端线程将事件传递给执行器线程的方法。我看到这样做的唯一方法是实现BlockingQueue,它也是同步的,以防止在尝试从另外两个线程添加元素时自然发生的争用情况
我实在看不出有什么方法可以解决这个非常简单的用例,而不需要同步或实现基本上相同的锁定算法所有的线程都不做同样的事情,只要考虑生产者和消费者的例子。消费者必须等待生产者完成其工作。锁定代码的关键部分通常比添加一个全新的线程&分布式队列系统更有意义,该系统将完成基本相同的工作,但使用更多的资源。-所有的线程都不做同样的事情,只是考虑生产者和消费者的例子。使用者必须等待生产者完成其工作。锁定代码的关键部分通常比添加一个全新的线程&分布式队列系统更有意义,该系统将完成基本相同的工作,但使用更多的资源。同步在多个连接之间起作用吗?我认为,每个连接都会创建多个线程,并且只在自己创建的线程中阻塞,但是ATM示例和您的示例表明,同步可以在所有线程上工作,而不管创建了哪个连接。如果是,现在我明白了。同步在所有线程上都有效:只有一个线程可以同时运行同步方法。当然,它仅在线程共享同步对象的同一实例时适用。是否共享同步对象的同一实例?怎样如果存在公共类ClassContainsSynchronoused{…},则用户将创建该类的新实例,B用户将创建另一个实例,实例将存储在不同的内存地址中。是否应该是静态的?如果对象不同,则同步没有意义。在我给出的示例中,服务器处理计数器。我们可以有一个包含两个计数器信息的类游戏。两个玩家之间的每场游戏将有一个实例,两个玩家的连接线程将在同一个实例上执行它们的代码。他们共享同一个实例,因为两个玩家使用唯一的id调用同一个游戏实例。我明白了,所以游戏实例应该存储在某个地方,以便a和B用户可以使用同一个游戏实例。非常感谢您的所有意见!同步在多个连接之间工作吗?我认为,每个连接都会创建多个线程,并且只在自己创建的线程中阻塞,但是ATM示例和您的示例表明,同步可以在所有线程上工作,而不管创建了哪个连接。如果是,现在我明白了。同步在所有线程上都有效:只有一个线程可以同时运行同步方法。当然,它仅在线程共享同步对象的同一实例时适用。是否共享同步对象的同一实例?怎样如果有公共c
lass CLASSCONTAINSSYNCHROIZED{…},用户将创建该类的新实例,B用户将创建另一个实例,实例将存储在不同的内存地址中。是否应该是静态的?如果对象不同,则同步没有意义。在我给出的示例中,服务器处理计数器。我们可以有一个包含两个计数器信息的类游戏。两个玩家之间的每场游戏将有一个实例,两个玩家的连接线程将在同一个实例上执行它们的代码。他们共享同一个实例,因为两个玩家使用唯一的id调用同一个游戏实例。我明白了,所以游戏实例应该存储在某个地方,以便a和B用户可以使用同一个游戏实例。非常感谢您的所有意见!