4.线程安全
出现线程安全的问题需要一个前提:多个线程同时操作同-一个资源
线程执行调用方法run,同一个资源是堆内存的
4.1售票例子
火车票的票源是固定的,购买渠道在火车站买,n多个窗口
线程的安全问题:多线程操作-一个资源,有可能出现安全问题
出现的原因:当一个线程还没有操作完成,另-一个线程就开始操作了
解决线程的安全问题:当一个线程没有完成全部操作的时候,其它线程不能操作
4.2同步代码块
同步代码块可以解决线程安全问题:格式synchronized关键字
synchronized (任意对象) {
//线程操作的共享资源
}
同步代码块,如何保证线程的安全性.
●同步代码块的执行原理:关键点就是对象锁
。线程执行到同步,判断锁是否存在
■如果锁存在,获取到锁,进入到同步中执行
■执行完毕,线程出去同步代码块,讲锁对象归还
。线程执行到同步判断锁所否存在
■如果锁不存在,线程只能在同步代码块这里等待锁的到来
使用同步:线程要先判断锁,然后获取锁,出去同步要释放锁,增加了许多步骤,因
此线程安全运行速度慢.牺牲性能不能牺牲数据安全
任意对象:在同步中这个对象称为对象锁简称锁官方的稳定称为对象监视器
线程执行到同步的时候
线程判断同步中的锁还有没有
线程获取这把锁,带着锁进入到同步的代码块中
执行同步中的程序,当线程出去同步代码块,锁要归还
4.3同步方法
I
当一个方法中,所有代码都是线程操作的共享内容,可以在方法的定义上添加同步的
关键字synchronized ,同步的方法,或者称为同步的函数.
●静态同步方法中有对象锁吗,锁对象是本类.class属性.这个属性表示这个类的
class文件的对象.
package com.sdjzu.thread3;
/*
* 购买火车票的窗口(Runnable接口的实现类)
* */
public class Ticket implements Runnable{
private int ticket=1000;
@Override
//重写接口的方法
public void run() {
while(true){
key();
}
}
//同步方法(this安全锁)
public synchronized void key() {
if(ticket>0){
try{Thread.sleep(1000);}
catch (Exception e){};
System.out.println(Thread.currentThread().getName()+":第"+ticket+"票");
ticket--;
}
}
}
package com.sdjzu.thread3;
/*
* 测试类
* */
public class TicketTest {
public static void main(String[] args) {
//创建Runnable接口的实现类
Ticket ticket=new Ticket();
//创建Thread对象,并传入实现类
Thread thread1=new Thread(ticket);
Thread thread2=new Thread(ticket);
Thread thread3=new Thread(ticket);
//启动线程,调用run方法
thread1.start();
thread2.start();
thread3.start();
}
}
在这里插入代码片