java中线程同步的几种方法

这些Java线程同步方法你用对了吗?
1 .同步方法锁定整个对象。
2 .同步代码块锁定指定对象。
3 、Volatile变量无法完全同步,仅保证可见性。

4 lock接口比synchronized接口更灵活,可以中断,可以超时。
5 . AtomicInteger原子类,无锁且线程安全。

6 ThreadLocal的每个线程都有一个独立的副本,互不影响。
7 .BlockingQueue使用队列来实现线程安全。

您在特定场景中使用哪个?

linux的线程同步方式有哪些

Linux系统中实际上有几种同步线程的方法。
六种主要类型是互斥锁、自旋锁、信号量、条件变量、读写锁和屏障。
但老实说,前三种是日常生活中用得最多的。
我们来一一说一下。

1 .互斥锁 准确的说,这个东西是一个特殊的全局变量,有两种状态,锁定和解锁。
要解锁的锁可以从某个线程获取。
一旦移动,锁就会关闭。
此后,只有持有锁的线程才能打开它。
其他想要获取它的线程将等待直到锁被释放。
这种锁分为几种类型:
普通锁:默认类型。
如果一个线程获得了锁,其他想要获得锁的线程就会排队,在解锁后根据优先级来获取。
这样就保证了公平性。
但是,如果一个线程加锁了一个已经加锁的普通锁,就会出现死锁。
打开一把已经关闭的普通锁,或者重新打开一把已经打开的锁,将会产生严重且不可预测的后果。
错误检测锁:这种锁比较智能。
如果锁定了之前锁定的错误检测锁,会直接报EDEADLK错误。
解锁已锁定的内容,或重新解锁已解锁的内容,也会报告 EPERM 错误。
嵌套锁:这种锁允许一个线程多次加锁,而不会造成死锁。
但如果其他线程想要获取它,就必须被当前线程锁定。
需要等待多次才能解锁。
解锁之前锁定的嵌套锁,或者重新解锁已经解锁的嵌套锁,也会报EPERM错误。
默认锁:此锁的行为不太固定,可以实现为上述三种锁之一。
重新锁定已解锁的项目、解锁先前锁定的项目或重新解锁已解锁的项目的后果是不可预测的。

2 自旋锁 自旋锁意味着连续投票。
如果线程没有获得锁,它不会像互斥锁那样休眠,而是会在尝试获得锁的同时不断轮询。
如果锁打开速度很快,则性能良好。
但如果锁还没有释放,仍然存在IO阻塞,其他线程就会保持空闲轮询,CPU会直接1 00%工作,这对于CPU来说特别昂贵。

3 信号量 信号量是一个计数器,用于管理共享有限资源的线程数量。
例如,一个资源只能被N个线程同时使用,信号量会记住当前有多少个线程正在使用它。
用完后,计数减一;当它用完时,计数加一。

多线程如何同步

现在我们来谈谈线程同步,特别是重要的部分和事件。

关键部分(CCriticalSection)
我以前在处理 Windows 服务时使用过这个。
假设您有一个特殊变量,例如计数器 g_TotalCount。
该变量必须由多个线程使用,但一次只能由一个线程修改,而不能由多个线程同时修改。
如果您不更改它,您的数据将变得混乱(这称为竞争条件)。

1 .定义:首先,我们需要一个像这样的临界区对象: C.P. CCriticalSection g_CriticalSection; 你需要一把钥匙,就像你需要一把门锁一样。

2 锁:在移动g_TotalCount之前,我们必须首先获得这个锁。
C.P. g_CriticalSection.Lock(); 在这一步,在多核CPU上,其他想要访问该变量的线程必须暂停或排队等待。
之前测试的时候,计数器会随机跳转,没有锁定,加减不准确。

3 .解锁:更改g_TotalCount后一定要归还锁。
C.P. g_CriticalSection.Unlock(); 这样其他线程就可以获取和修改锁。

事件(CEvent)
这与临界区不同,而更像是发送信号。
让我们考虑一下这种情况。
线程正在等待某些事情发生,例如等待用户单击确认按钮或等待网络数据包到达。
对于其他活动,请点击这里。

状态:事件有两种状态:有信号(有人会打电话给你)和无信号(没有人会打电话给你)。
默认情况下,它是在没有信号的情况下创建的。
类型: 自动事件:这样更安全。
当您喊叫(设置事件)时,其他人可以听到(等待事件)。
尖叫过后又会安静下来,不用担心。
上次写网络监控程序时,我使用了自动事件。
主线程正在等待监视新连接。
建立新连接时会设置一个事件。
将启动主线程来处理它。
处理完之后,可能又会变成Wait。
下次连接时事件会自动清除并重置,因此非常流畅。
人工事件:这有点冗长。
当您喊叫(设置事件)时,其他人可以听到(等待事件)。
然而,仅此事件并不能消除声音,即使在其他人听到之后也是如此。
要恢复静音,必须手动调用Reset()方法。
上次使用了人工事件,但是忘记重置了,导致主线程等待了很长时间。
我变得非常焦虑,所以我在不同的位置尝试了 Reset()。
我发现我需要添加 .因此,在使用人工事件时,必须特别注意确保所有可能的位置都被重置。

一般来说,临界区适合保护小段代码或者多个变量不被多个线程同时修改,以保证数据的一致性。
事件适用于线程之间的通知和触发。
例如,当一个线程完成执行某件事时,它会告诉另一个线程要做什么。
使用时需要清楚了解场景,避免混乱。

Java 线程同步几种方式

2 02 3 年,朋友问了我一个问题。
He said that the synchronization method is to use the synchronized keyword, right? I said yes, this method can ensure that only one thread can run at a time.
Then he asked: What about synchronized code blocks? I said that it also uses synchronized, but it changes the code block, not the entire method.
接着他提到volatile关键字,我解释说,volat ile是用来提供变量的可见性,确保每次访问变量时都是最新的值.
他再次询问有关重新入境禁令的问题。
我说这个是JavaSE5 .0之后引入的。
The ReentrantLock class can provide a more flexible locking mechanism.
最后, 他说要用局部变量实现线程同步, 我愣了一下, 然后说这个嘛,局部变量通常不需要同步, 因为它们的作用域很小,但如果确实需要,可以考虑使用局部变量的引用来同步.
After hearing this, he nodded and said, "Oh, I understand."算了,你自己想办法吧。