java线程安全问题如何解决
- 重写 Runnable接口种的run方法
package cn.tread;
public class runnable implements Runnable {
private int ticket =100;
@Override
public void run() {
while (true){
if (ticket>0){
System.out.println(Thread.currentThread().getName()+"正在买"+ticket+"张票");
ticket--;
}
}
}
- 创建一个刚才写的实例对象 调用
New 一个Thread对象吧刚才的实例对象放进去用start方法运行
package cn.tread;
public class demo {
public static void main(String[] args) {
runnable demo1= new runnable();
// Thread用来创建线程// Thread用来创建线程 构造方法种传递runnable实现类对象
Thread to1 = new Thread(demo1);
Thread to2 = new Thread(demo1);
Thread to3 = new Thread(demo1);
to1.start();
to2.start();
to3.start();
}
}
安全问题产生的原因
本案例开启三个线程,三个线程抢夺执行权,他执行到if语句就会失去cpu执行权,速度太快都在执行第一个的时候同时打印
解决方法
- 同步代码块
package cn.线程;
public class runnable implements Runnable {
private int ticket =100;
Object obj = new Object();
@Override
public void run() {
while (true){
//同步代码块 synchronized
//可以使用任意对象Synchronized是Java中解决并发问题的一种最常用最简单的方法 ,他可以确保线程互斥的访问同步代码
synchronized (obj){
if (ticket>0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在买"+ticket+"张票");
ticket--;
}else {
break;
}
}
}
}
- 同步方法
定义格式
修饰符 synchronized 返回值类型 方法名(参数列表){
共享数据的代码 / 有问题代码可能出现重复数据
}
package cn.线程;
public class runnable implements Runnable {
private int ticket =100;
Object obj = new Object();
@Override
public void run() {
while (true){
// 同步代码块
//可以使用任意对象
payket();
}
}
public synchronized void payket(){
if (ticket>0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在买"+ticket+"张票");
ticket--;
}
}
- 锁机制
- public class ReentrantLock implements Lock, java.io.Serializable
- 如果使用Lock 需要调用Lock子类 renntrantlock
- Lock 更加先进以及好用
lock 获取锁
unlock 释放锁