------- android培训、java培训、期待与您交流! ----------
- 多线程安全问题
通过分析发现打印出0,-1,-2等错票
多线程的运行出现了安全问题
问题的原因:
当多条语句操作同一线程的共享数据时,一个线程只执行了多条语句中的一部分,还没有执行完,就转入冻结状态
这时另一个线程参与进来,造成对共享数据的破坏
解决办法:
对操作共享数据的多条语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与!
java对于多线程的安全问题提供了解决方式
1.线程的同步: 就是同步代码块
synchronized (对象) {
需要被同步的代码
}
2.同步函数:public synchronized void function(){}
(1)同步函数的锁是“this”,
静态类进入内存时,内存中本没有内存对象,但是,有该类对应的字节码文件对象。
类名.class 类型是Class
(2)故静态类同步函数的锁是“类名.class”,即Class类型的对象
同步代码块运行原理:(同步代码块可以理解为一个有自动开关的容器)
synchronized (对象)中的“对象”就相当于一把锁(标志),最开始该锁默认是打开的,
一旦有一个进程进入该方法体内,该锁便自动关上,只有当该进程将多条处理共享数据的语句
(期间该进程可能出现冻结状态)都执行完毕后,锁才被自动打开, 第二个拥有cpu执行权的在进入,继续执行
这就保证了线程的同步
同步的前提:
1.必须是两个线程或多个线程以上
2.必须是使用同一把锁
好处:解决了线程的安全问题
弊端:每个线程都需要判断锁,较为消耗资源
如何找安全问题?
1.哪些代码是多线程运行代码
2.哪些数据时共享数据
3.哪些是线程执行过程中,操作共享数据的语句
class Tickt implements Runnable{
private int tickts=100;
Object object=new Object();
public void run(){
while(true)
{
synchronized (object) {
if(tickts>0)
{ //可能的异常,共三个线程thread-0,thread-1,thread-2
//假设tickts=1;thread-0进来,但这时thread-0突然停止运行,thread-1进来,一次类推
//就可能导致tickts=0,-1,,-2
try {
Thread.sleep(10);
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()+"票数:"+tickts--);
}
}
}