线程状态
线程有六种状态:
线程安全
使用synchronized关键字以及同步方法解决线程安全问题
线程安全问题:就是对不同的线程访问同一个资源时(共享资源)因为线程的执行先后问题,导致数据发生问题
package package27Threds.Demo01;
public class Demo01Threds_Ticket {
public static void main(String[] args) {
//创建Runnable接口的实现类对象
RunnableImpl run = new RunnableImpl();
//创建Thread类对象,构造方法中传递Runnable接口实现类的对象
Thread thread01 = new Thread(run);
Thread thread02 = new Thread(run);
Thread thread03 = new Thread(run);
//使用start开启线程
thread01.start();
thread02.start();
thread03.start();
}
}
package package27Threds.Demo01;
public class RunnableImpl implements Runnable{
int ticket = 100;//共有100张票
Object obj = new Object();
/*
* 关键字Synchronized解决线程安全
* 同步锁对象(obj)
* */
/*@Override
public void run() {
while (true){
synchronized (obj){
if (ticket>0) {
//提高安全问题出现的概率,让程序睡眠
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->"+"这是卖出的第 "+ticket+" 张票");
ticket--;
}
}
}
}*/
/*
* 使用同步方法解决线程安全
* 同步方法会将方法内部的代码锁住
* 每次只让一个资源执行
* 同步方法的锁对象是-->new RunnableImpl,也就是this
* */
@Override
public void run() {
while (true){
payTicket();
}
}
/*
* 定义同步方法
* */
public synchronized void payTicket(){
if (ticket>0) {
//提高安全问题出现的概率,让程序睡眠
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->"+"这是卖出的第 "+ticket+" 张票");
ticket--;
}
}
}
使用Lock接口对线程安全问题进行解决
/*
* 第三种方法Lock接口
* Lock 实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作
* Lock接口中的方法:void lock();获取锁 void unlock();释放锁
* java.util.concurrent.locks.ReentrantLock implements Lock接口
*
* 使用步骤:
* 1.在成员位置创建一个reentrantLock对象
* 2.在可能出现安全问题的代码前调用Lock接口中的方法lock();获取锁
* 3.在可能出现安全问题的代码后调用Lock接口中的方法unlock();释放锁
* */
@Override
public void run() {
while (true){
l.lock();
if (ticket>0) {
//提高安全问题出现的概率,让程序睡眠
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->"+"这是卖出的第 "+ticket+" 张票");
ticket--;
}
l.unlock();
}
}
/*
* 第三种方式的优化
* */
@Override
public void run() {
while (true){
l.lock();
if (ticket>0) {
//提高安全问题出现的概率,让程序睡眠
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"-->"+"这是卖出的第 "+ticket+" 张票");
ticket--;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
l.unlock();//无论程序是否异常都会释放锁
}
}
}
}