Multithreading - Concurrent Programming (5) - Thread Safety and Synchronization with Instance Notes

Thread safety issues
Multiple threads may share (access) the same resource
//For example, accessing the same object, the same variable, and the same file
When multiple threads access the same resource, it is easy to cause data confusion and data security issues. thread safety problem

Under what circumstances will thread safety issues occur when
multiple threads share the same resource
and at least one thread is performing a write operation

Example: The
problem
of depositing money and withdrawing money has two threads : depositing money and withdrawing money.

   存钱                      取钱
   线程1         余额         线程2
   1000  《----1000------》 1000
   1000+1000-----》2000
                500 《-----1000-500


//correct: the balance should be 1500 after the end, not 500


There are 2 threads for selling tickets

   卖票                      卖票
   线程1         票数         线程2
   1000  《----1000------》 1000
   1000-1-----》999
                999 《-----1000-1

//correct: the balance should be 998 after the end, not 999

Example of buy ticket problem error (not thread synchronization):

public class love implements Runnable{
    private int piao=3000;//有3000张票
    public boolean sale() {//ture代表还有票;false代表没有票了
        if(piao<1) return false;
         piao--;//卖1张票
         
         //细化piao--;
         //寄存器=piao;
         //寄存器=寄存器-1;
         //piao=寄存器;
         
         String sk =Thread.currentThread().getName();//获取当前线程(买票窗口)的名字
         System.out.println(sk+"卖了1张票,还剩下"+piao+"张");
         return piao>1;
    }
    public void run() {
         while(sale());//循环执行;直至卖完票返回false
    }
}

public class Main {
    public static void main(String[] a) {
        love tjlove =new love();
        for(int i=1;i<=4;i++) {//循环4次;产生4个线程(窗口)卖票
            Thread tj = new Thread(tjlove());
            tj.setName(""+i);
            tj.start();
        }
    }
}

Partial output:

Thread Safety Issues - Analyzing Issues

线程A和B对类中1个变量值为17进行+1操作
最终结果为2个18

Thread safety problem - solution
Lock:

过程:首先线程A先访问到这个17,读上来后进行加锁并进去+1的操作改为18
并且17在加锁期间其它线程都不能访问
改完之后再进行写入,然后再解锁17
然后再由线程B去访问它,再进行加锁,重复上面操作变成19再解锁
这样做能保证在同一时间只有1个线程去访问它,这样就保证了安全;之前错误是由于这些线程一起去访问了它

Thread synchronization
The locking operation just mentioned is thread synchronization technology. Thread synchronization technology
can be used to solve thread safety problems
. There are two ways of thread synchronization in Java:
1. Synchronization statement
2. Synchronization method

Thread Synchronization - Synchronization Statement

public class love implements Runnable{
	private int piao=3000;//本人cpu单核性能过强,数据量大些才能看到是4个线程在卖票
	public boolean sale() {
		synchronized(this) {//1个线程获取这个对象的锁,并加锁;    synchronized作用于整个语句
		//this指向当前对象
		//不能用new Object();这样会产生新的对象,产生新的锁
		//把this换成"123",效果基本一样;因为其存在常量值里,每次访问的对象一样
			if(piao<1) return false;
			piao--;
			String sk =Thread.currentThread().getName();
			System.out.println(sk+"卖了1张票,还剩下"+piao+"张");
			return piao>0;
			}
	}
	public void run() {
		 while(sale());
	}
}

Partial output:

The principle of synchronize(obj) 1.
Each object has an internal lock (intrinsic lock) or monitor lock (monitor lock) associated with it
2. The first thread that executes the synchronization statement can obtain the internal Lock, release the lock after executing the code in the synchronization statement
3. As long as one thread holds the internal lock, other threads will not be able to acquire the lock at the same time
✓ When they try to acquire this lock, they will enter BLOCKED State
4. When multiple threads access the same synchronized(obj) statement,
obj must be the same object to achieve synchronization

Thread Synchronization - Synchronization Methods

public class love implements Runnable{
    private int piao=3000;
    public synchronized boolean sale() { //synchronized作用于整个方法
            if(piao<1) return false;
            piao--;
            String sk =Thread.currentThread().getName();
            System.out.println(sk+"卖了1张票,还剩下"+piao+"张");
            return piao>0;
    }
    public void run() {
         while(sale());
    }
}

Synchronized cannot modify
the essence of the constructor synchronization method.
Instance method: synchronized (this)
Static method: synchronized (Class object)

Synchronized statements are a little more flexible than synchronized methods.
Synchronized statements can precisely control the range of code that needs to be locked, reduce the number of threads in the BLOCKED state, and make full use of labor.

After using the thread synchronization technology,
although the thread safety problem is solved, it reduces the execution efficiency of the program.
Because there will be waiting threads when the lock is added, there are more lock and unlock operations,
so the thread is only used when it is really necessary. Sync technology

Guess you like

Origin blog.csdn.net/weixin_59624686/article/details/124093334