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