当前位置:网站首页>Concurrent shared model management
Concurrent shared model management
2022-06-24 23:11:00 【Under the seven kingdoms, I want 99】
Concurrent shared model management
1 Sharing issues
Two threads add and subtract the same number , Because of context switching , The value cannot be updated , Thus affecting the statistical results .
static int counter = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
counter++;
}
}, "t1");
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
counter--;
}
}, "t2");
t1.start();
t2.start();
t1.join();
t2.join();
log.debug("{}",counter);
/* Running results : -2470 */
Problem specification
The above result may be positive 、 negative 、 zero . because Java Autoincrement of static variables in , Self subtraction is not an atomic operation , Analyze from bytecode
about i++ operation , Corresponding JVM Bytecode
getstatic i // Get static variables i Value
iconst_1 // Prepare constants 1
iadd // Self increasing
putstatic i // Store the modified value in a static variable i
about i– operation
getstatic i // Get static variables i Value
iconst_1 // Prepare constants 1
isub // Self reduction
putstatic i // Store the modified value in a static variable i
Java The memory model of is as follows , Complete the self increment of static variables , Self subtraction requires data exchange between main memory and working memory :

Execute... In a single thread , No problem ; In multithreading , Positive numbers may occur , negative .
A critical region
- There is no problem for a program to run multiple threads
- The problem is that multiple threads access shared resources
- The problem is that multiple threads access shared resources
- Instruction interleaving occurs when multiple threads read and write to shared resources , There will be problems
- If there are multithreaded read and write operations on shared resources in a code block , Call this code block a critical area
Here is an example :
static int counter = 0;
static void increment()
// A critical region
{
counter++;
}
static void decrement()
// A critical region
{
counter--;
}
Race condition
Multiple threads execute in a critical area , The results are unpredictable due to the different execution sequences of the code , That is, a race condition occurs
2 synchronized
In order to avoid the occurrence of race conditions in the critical region , There are many ways to get there
- Blocking solutions :synchronized,Lock
- Non blocking solution : Atomic variable
synchronized, Commonly known as 【 Object lock 】, It uses mutual exclusion to make the same At most one thread at a time can hold 【 Object lock 】, Other threads want to get this again 【 Object lock 】 It will block when . This ensures that you have a lock Threads can safely execute code in critical areas , Don't worry about thread context switching .
java Mutual exclusion and synchronization in synchronized Keyword to complete , The difference between the following :
Mutual exclusion is to ensure that the race condition in the critical region occurs , Only one thread can execute critical area code at a time
Synchronization is due to the sequence of thread execution 、 Different order 、 A thread needs to wait for other threads to run to a certain point
grammar
synchronized( object ) // Threads 1, Threads 2(blocked)
{
A critical region
}
// When a thread 1 Enter the critical area A context switch occurs , Threads 2 Because there is no object lock Blocked outside
Case study
static int counter = 0;
static final Object room = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
synchronized (room) {
counter++;
}
}
}, "t1");
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
synchronized (room) {
counter--;
}
}
}, "t2");
t1.start();
t2.start();
t1.join();
t2.join();
log.debug("counter = {}",counter);
}
/* Running results : counter = 0 */
explain :
synchronized( object ) Objects in the , Imagine a room (room), There is only one entrance ( door ) Only one person can enter the room at a time Calculate , Threads t1,t2 Imagine two people
When a thread t1 Execute to synchronized(room) Time is like t1 Into this room , And locked the door and took the key , Execute... In the door count++ Code
At this time, if t2 Also run to synchronized(room) when , It found the door locked , Can only wait outside the door , A context cut has occurred in , Blocked up
Even in the middle t1 Of cpu Unfortunately, the time slice has run out , Kicked out of the door ( Don't mistakenly understand that the object can be locked and executed all the time ), The door was still locked ,t1 Still holding the key ,t2 The thread is still blocked and can't get in , Only next time t1 Only when you get the time slice again Can open the door and enter
When t1 After execution synchronized{} Code in block , This is the time to start from obj Come out of the room and unlock the door , Wake up the t2 Thread key Give him the spoon .t2 The thread can then enter obj room , Lock the door, take the key , Carry out its count-- Code
Summary
synchronized In fact, object lock is used to ensure the atomicity of the code in the critical region , The code in the critical area is inseparable from the outside , Will not be cut by the thread Change places to interrupt .
If you put synchronized(obj) Put it in for Outside of the loop , How to understand ?
- So the whole for A cycle is a whole , Before the end of the cycle , Other threads cannot run , Guaranteed atomicity .
If t1 synchronized(obj1) and t2 synchronized(obj2) How it will work ?
- sync It's a lock object . Above , Use two different objects , Then the threads control each other separately , It will not block because of the mutual influence of locks .
If t1 synchronized(obj) and t2 What happens if you don't add ?
- So thread t1 Accuracy is guaranteed , Threads t2 No guarantee , The final result is not guaranteed ,sync A lock is aimed at an object , You need to associate that all threads use the same object .
Object oriented case transformation
// To control with a lock Add reduce Inquire about
class Room {
int value = 0;
public void increment() {
synchronized (this) {
value++;
}
}
public void decrement() {
synchronized (this) {
value--;
}
}
public int get() {
synchronized (this) {
return value;
}
}
}
Test class
@Slf4j
public class Test1 {
public static void main(String[] args) throws InterruptedException {
Room room = new Room();
Thread t1 = new Thread(() -> {
for (int j = 0; j < 5000; j++) {
room.increment();
}
}, "t1");
Thread t2 = new Thread(() -> {
for (int j = 0; j < 5000; j++) {
room.decrement();
}
}, "t2");
t1.start();
t2.start();
t1.join();
t2.join();
log.debug("count: {}" , room.get());
}
}
/* Running results : count: 0 */
synchronized Used in methods
Class object
class Test{
public synchronized void test() {
}
}
// Equivalent to
class Test{
public void test() {
synchronized(this) {
}
}
}
Class itself
class Test{
public synchronized static void test() {
}
}
// Equivalent to
class Test{
public static void test() {
synchronized(Test.class) {
}
}
}
Thread eight locks
- result 12 or 21
@Slf4j(topic = "c.Number")
class Number{
public synchronized void a() {
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n1.b(); }).start();
}
- 1s after 12, or 2 1s after 1
@Slf4j(topic = "c.Number")
class Number{
public synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n1.b(); }).start();
}
- 3 1s 12 or 23 1s 1 or 32 1s 1
@Slf4j(topic = "c.Number")
class Number{
public synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
public void c() {
log.debug("3");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n1.b(); }).start();
new Thread(()->{
n1.c(); }).start();
}
- 2 1s after 1
@Slf4j(topic = "c.Number")
class Number{
public synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n2.b(); }).start();
}
- 2 1s after 1
@Slf4j(topic = "c.Number")
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n1.b(); }).start();
}
- 1s after 12, or 2 1s after 1
@Slf4j(topic = "c.Number")
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public static synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n1.b(); }).start();
}
- 2 1s after 1
@Slf4j(topic = "c.Number")
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n2.b(); }).start();
}
- 1s after 12, or 2 1s after 1
@Slf4j(topic = "c.Number")
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public static synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n2.b(); }).start();
}
边栏推荐
- 剑指 Offer 42. 连续子数组的最大和
- [postgraduate entrance examination English] prepare for 2023, learn list8 words
- [WSL] SSH Remote Connection and host port forwarding configuration
- Recommended course: workplace writing training
- 京东618会议平板排行榜公布,新锐黑马品牌会参谋角逐前三名,向国货老大华为学习
- 力扣解法汇总515-在每个树行中找最大值
- 【nvm】
- [laravel series 7.9] test
- Research and investment strategy report on China's building steel structure anticorrosive coating industry (2022 Edition)
- MySQL kills 10 people. How many questions can you hold on to?
猜你喜欢

并发之共享模型管程
![[laravel series 7.9] test](/img/49/4b470a8b309bab4a83eed930dcce65.png)
[laravel series 7.9] test

花房集团二次IPO:成于花椒,困于花椒

Simulated 100 questions and online simulated examination of high voltage electrician examination in 2022
![[ROS play with turtle turtle]](/img/94/4d1063f063d115aeef5cdf099278f8.png)
[ROS play with turtle turtle]

23研考生注意啦!备考期间最容易中招的骗局,居然是它们?!

2022 safety officer-b certificate examination question bank and answers

Solution to the login error of tangdou people

【Laravel系列7.9】测试

对抗训练理论分析:自适应步长快速对抗训练
随机推荐
EPICS记录参考4--所有输入记录都有的字段和所有输出记录都有的字段
How to integrate Huawei cloud function services in fluent
[postgraduate entrance examination English] prepare for 2023, learn list9 words
记录一下MySql update会锁定哪些范围的数据
Financial management [3]
JD 618 conference tablet ranking list announced that the new dark horse brand staff will compete for the top three, learning from Huawei, the leader of domestic products
Epics record reference 3 -- fields common to all records
研究生宿舍大盘点!令人羡慕的研究生宿舍来了!
推送Markdown格式信息到釘釘機器人
Research Report on market evaluation and investment direction of Chinese dermatology drugs (2022 Edition)
Source code reading | the process of reading text format STL by openmesh
Memory alignment of structures
Tech talk activity review kubernetes skills of cloud native Devops
倍加福(P+F)R2000修改雷达IP
Research and investment strategy report on China's building steel structure anticorrosive coating industry (2022 Edition)
Daily practice (22): maximum sum of continuous subarrays
Servlet
Docker installation redis- simple without pit
【Mongodb】READ_ ME_ TO_ RECOVER_ YOUR_ Data, the database is deleted maliciously
Cat write multiline content to file