线程安全
原因
多个线程同时操作一个数据时,会导致数据不安全
名词介绍
同步:同时只能被一个线程执行(线程安全)
异步:同时能被多个线程执行(线程不安全)
解决方案
思路:保证同时只能有一个线程在操作数据,并且锁对象是同一个
方案一:同步代码块
语法:
synchronize(锁对象){
要同步的代码
}
注意
锁对象:任何一个类的对象都可以作为锁对象
方案二:同步普通方法
语法
访问权限修饰符 synchronize 返回值类型 方法名(形参列表){
方法体
return返回值;
}
注意:谁调用同步普通方法,谁就是锁对象
方案三:同步静态方法
语法
访问权限修饰符 static synchronize 返回值类型 方法名(形参列表){
方法体
return返回值;
}
注意:
锁对象:该类的类对象,切只可使用一次
死锁(了解)
为什么会产生死锁?
多个线程互相持有对方所需的锁资源
怎么避免
尽量不要再同步中使用同步
如:
尽量不要再同步方法中使用同步方法和同步代码块
尽量不要再同步代码块中使用同步方法和同步代码块
线程的休眠与唤醒
休眠
有限期休眠:sleep 或 wait
无限期休眠:wait
sleep 和 wait的区别
相同点:
都能使程序进入休眠
不同点:
sleep:
1、sleep方法是由Thread类提供的
2、sleep只能使用Thread类名或Thread对象名调用
3、使用sleep进行休眠,不会释放锁资源
4、sleep可以在任何一处地方使用
wait:
1、wait方法是由Object类提供的
2、wait只能使用该同步方法或该同步代码块的锁对象调用
3、使用wait进行休眠,会释放锁对象
4、wait只能在同步方法或同步代码块中使用
5、wait后没有参数,表示无限期休眠
唤醒
对象.notify():随机唤醒一个使用该对象作为锁对象的线程
对象.notifyall():唤醒所有使用该对象作为锁对象的线程
总结
为什么要使用同步?
因为多个线程操作同一个数据,会导致数据不安全,出现错乱的数据,(如重复数据或负数)
如何解决?
使用同步解决
同步的方式
同步代码块
注意:同步代码块的锁对象是由自己指定的
同步普通方法
注意:锁对象是调用该方法的对象
同步静态方法
注意:锁对象是该类的类对象
使用同步要注意什么?
1、分析需要加同步的地方
2、保证锁对象是同一个对象
3、避免死锁
线程间通讯:
休眠:
让线程进入休眠状态,不在抢夺CPU执行权
唤醒:
让线程从休眠状态转换为就绪状态,准备抢夺CPU执行权