出现线程安全原因是:
线程的执行 是按照cpu的分配执行的,当这个线程获取到了相关的时间片,那么就会执行,时间片到了就会又重新进入等待的过程;
那么可能就出现 语句还没有执行完,但是另一个线程又开始执行这个语句的情况了;
实现安全的方式:
1.同步代码块
2.同步方法
同步代码块: 在代码块声明上 加上synchronized
synchronized (锁对象) {
可能会产生线程安全问题的代码
}
同步代码块中的锁对象可以是任意的对象;但多个线程时,要使用同一个锁对象才能够保证线程安全。
同步方法:在方法声明上加上synchronized
public synchronized void method(){
可能会产生线程安全问题的代码
}
public static synchronized void method(){
可能会产生线程安全问题的代码
}
同步方法中锁对象 指的是 this
静态同步方法中的锁对象是 类名.class
使用同步锁 也会出现弊端:
当线程任务中出现多个同步锁时,就可能相互都被锁住,程序出现无限等待;
- 使用lock (接口) 进行 加锁;
3//创建Lock锁对象 Lock ck = new ReentrantLock();
Lock ck = new ReentrantLock();
@Override
public void run() {
//模拟卖票
while(true){
//synchronized (lock){
ck.lock();
if (ticket > 0) {
//模拟选坐的操作
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);
}
ck.unlock();
//}
}
}
}