1.什么是线程安全?
多个线程竞争同一资源,可能导致数据错误。
例子:12306买票系统,同一张票被多人买,就会出现线程安全问题。
2.创建线程的两种方式
1.(1)线程类实现runnable接口
(2)创建线程类对象
(3)thread(线程类对象).start()
优点:一个线程可以启动多次,thread()参数可以为同一线程对象,属性方法可以唯一。
2.(1)线程类继承Thread,
(2)创建线程类对象
(3)线程类对象调用start()方法
缺点:一个线程只能启动一次,创建的线程对象的属性和方法不同,属性方法不唯一。
3.解决线程安全的方法
1.同步代码块
synchronized()参数为锁,锁必须为所有线程对象共有,方法体里写同步的数据。
例子:
//同步代码块
synchronized(ticket) { //锁必须唯一,两个线程对象所共有
//方法里写同步的数据
ticket.ticketnum--;
System.out.println(Thread.currentThread().getName() + "线程买到票" + ticket.ticketnum);
}
2.手动加锁
自己写锁,锁必须为线程对象所共有。try里写加锁和同步的数据,加锁后必须释放锁,释放锁的过程写在finally里一定执行。
//手动加锁,释放锁,锁必须唯一,两个线程对象所共有
private Lock lock = new ReentrantLock(); //reentrant重入锁
try{
lock.lock();
ticket.ticketnum--;
System.out.println(Thread.currentThread().getName() + "线程买到票" + ticket.ticketnum);
}finally{ //finally一定执行,不管抓没抓到
lock.unlock();
}
}
3.同步方法
同步方法必须为线程对象所共有,里面写同步的数据。
例子:
//同步方法,方法必须唯一
public synchronized void buyticket(){
ticket.ticketnum--;
System.out.println(Thread.currentThread().getName() + "线程买到票" + ticket.ticketnum);
}