您的位置:首页 > 其它

如何解决多线程不安全

2017-08-21 16:45 204 查看

如何解决多线程不安全

比如买票,会出现一票多求,负票等问题

解决;
java提供了一个同步机制(同步锁):synchronized  :包装其中的多条语句

例:
synchronized(对象){
多条语句对共享语句进行操作
}
对象:需要使用同一个对象,封装到外面
注意:任意对象,但必须创建,也必须存在


线程安全的检测条件:

1)看我们当前的环境是否属于多线程程序

2)当前的多线程程序中是否有共享数据

3)是否多条语句对共性数据进行操作

需求:

模拟电影院售票案例,现有100张票,三家影院同时出售,卖出每张票中间会有100毫秒的延迟

代码:

public class SellTickets implements Runnable {

//定义票数
private int tickets = 1;

Demo d = new Demo();

@Override
public void run() {
while(tickets<=100){
//同步锁
synchronized(d){
if(tickets<=100){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+"正在出售第"+(tickets++)+"张票");
}
}
}

}


}

class Demo{}

public static void main(String[] args) {

SellTickets st = new SellTickets();

//创建线程对象
Thread th1 = new Thread(st, "窗口一");
Thread th2 = new Thread(st, "窗口二");
Thread th3 = new Thread(st, "窗口三");

//启动线程
th1.start();
th2.start();
th3.start();
}


结果:

窗口一:正在出售第1张票

窗口一:正在出售第2张票

窗口一:正在出售第3张票

窗口三:正在出售第4张票

窗口三:正在出售第5张票

窗口二:正在出售第6张票

窗口二:正在出售第7张票

窗口三:正在出售第8张票

窗口三:正在出售第9张票

窗口一:正在出售第10张票

窗口一:正在出售第11张票

窗口三:正在出售第12张票

窗口二:正在出售第13张票

窗口二:正在出售第14张票

窗口三:正在出售第15张票

窗口三:正在出售第16张票

窗口一:正在出售第17张票

窗口一:正在出售第18张票

窗口一:正在出售第19张票

窗口三:正在出售第20张票

窗口三:正在出售第21张票

窗口三:正在出售第22张票

窗口三:正在出售第23张票

窗口三:正在出售第24张票

窗口三:正在出售第25张票

窗口三:正在出售第26张票

窗口三:正在出售第27张票

窗口二:正在出售第28张票

窗口二:正在出售第29张票

窗口二:正在出售第30张票

窗口三:正在出售第31张票

窗口三:正在出售第32张票

窗口三:正在出售第33张票

窗口三:正在出售第34张票

窗口一:正在出售第35张票

窗口三:正在出售第36张票

窗口二:正在出售第37张票

窗口三:正在出售第38张票

窗口三:正在出售第39张票

窗口三:正在出售第40张票

窗口三:正在出售第41张票

窗口三:正在出售第42张票

窗口一:正在出售第43张票

窗口三:正在出售第44张票

窗口三:正在出售第45张票

窗口三:正在出售第46张票

窗口三:正在出售第47张票

窗口三:正在出售第48张票

窗口三:正在出售第49张票

窗口三:正在出售第50张票

窗口二:正在出售第51张票

窗口二:正在出售第52张票

窗口二:正在出售第53张票

窗口二:正在出售第54张票

窗口二:正在出售第55张票

窗口三:正在出售第56张票

窗口一:正在出售第57张票

窗口一:正在出售第58张票

窗口三:正在出售第59张票

窗口三:正在出售第60张票

窗口三:正在出售第61张票

窗口三:正在出售第62张票

窗口三:正在出售第63张票

窗口三:正在出售第64张票

窗口三:正在出售第65张票

窗口二:正在出售第66张票

窗口三:正在出售第67张票

窗口三:正在出售第68张票

窗口三:正在出售第69张票

窗口三:正在出售第70张票

窗口三:正在出售第71张票

窗口三:正在出售第72张票

窗口三:正在出售第73张票

窗口三:正在出售第74张票

窗口一:正在出售第75张票

窗口三:正在出售第76张票

窗口三:正在出售第77张票

窗口三:正在出售第78张票

窗口三:正在出售第79张票

窗口三:正在出售第80张票

窗口二:正在出售第81张票

窗口三:正在出售第82张票

窗口一:正在出售第83张票

窗口三:正在出售第84张票

窗口三:正在出售第85张票

窗口二:正在出售第86张票

窗口二:正在出售第87张票

窗口三:正在出售第88张票

窗口三:正在出售第89张票

窗口一:正在出售第90张票

窗口一:正在出售第91张票

窗口三:正在出售第92张票

窗口三:正在出售第93张票

窗口二:正在出售第94张票

窗口三:正在出售第95张票

窗口一:正在出售第96张票

窗口一:正在出售第97张票

窗口三:正在出售第98张票

窗口二:正在出售第99张票

窗口二:正在出售第100张票

使用同步机制解决了线程的安全问题,但是我们并没有看到具体的锁对象是谁,JDK5以后java提供了接口Lock,里面又提供了一些方法:

public void lock()获取锁

public void unlock():释放锁

Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作
由于该Lock接口不能实例化,提供了子实现类:ReentrantLock


代码:

public class MyLock implements Runnable{
private int tickets = 1;
//创建锁对象
Lock l = new ReentrantLock();

@Override
public void run() {
while(tickets <= 100){
l.lock();
if(tickets<=100){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+"正在出售第"+(tickets++)+"张票");
}
l.unlock();
}

}


}

public static void main(String[] args) {

MyLock ml = new MyLock();

//创建多线程对象
Thread th1 = new Thread(ml, "窗口一");
Thread th2 = new Thread(ml, "窗口二");
Thread th3 = new Thread(ml, "窗口三");

th1.start();
th2.start();
th3.start();
}


结果:

窗口一:正在出售第1张票

窗口二:正在出售第2张票

窗口二:正在出售第3张票

窗口二:正在出售第4张票

窗口二:正在出售第5张票

窗口二:正在出售第6张票

窗口二:正在出售第7张票

窗口二:正在出售第8张票

窗口二:正在出售第9张票

窗口二:正在出售第10张票

窗口二:正在出售第11张票

窗口三:正在出售第12张票

窗口一:正在出售第13张票

窗口二:正在出售第14张票

窗口三:正在出售第15张票

窗口一:正在出售第16张票

窗口二:正在出售第17张票

窗口二:正在出售第18张票

窗口二:正在出售第19张票

窗口三:正在出售第20张票

窗口三:正在出售第21张票

窗口三:正在出售第22张票

窗口一:正在出售第23张票

窗口二:正在出售第24张票

窗口二:正在出售第25张票

窗口二:正在出售第26张票

窗口二:正在出售第27张票

窗口二:正在出售第28张票

窗口二:正在出售第29张票

窗口二:正在出售第30张
4000


窗口三:正在出售第31张票

窗口三:正在出售第32张票

窗口一:正在出售第33张票

窗口二:正在出售第34张票

窗口三:正在出售第35张票

窗口一:正在出售第36张票

窗口二:正在出售第37张票

窗口二:正在出售第38张票

窗口二:正在出售第39张票

窗口二:正在出售第40张票

窗口二:正在出售第41张票

窗口二:正在出售第42张票

窗口二:正在出售第43张票

窗口二:正在出售第44张票

窗口二:正在出售第45张票

窗口二:正在出售第46张票

窗口二:正在出售第47张票

窗口三:正在出售第48张票

窗口三:正在出售第49张票

窗口三:正在出售第50张票

窗口三:正在出售第51张票

窗口三:正在出售第52张票

窗口一:正在出售第53张票

窗口二:正在出售第54张票

窗口二:正在出售第55张票

窗口二:正在出售第56张票

窗口三:正在出售第57张票

窗口三:正在出售第58张票

窗口一:正在出售第59张票

窗口二:正在出售第60张票

窗口二:正在出售第61张票

窗口二:正在出售第62张票

窗口二:正在出售第63张票

窗口二:正在出售第64张票

窗口二:正在出售第65张票

窗口二:正在出售第66张票

窗口二:正在出售第67张票

窗口二:正在出售第68张票

窗口二:正在出售第69张票

窗口二:正在出售第70张票

窗口三:正在出售第71张票

窗口一:正在出售第72张票

窗口二:正在出售第73张票

窗口二:正在出售第74张票

窗口二:正在出售第75张票

窗口二:正在出售第76张票

窗口二:正在出售第77张票

窗口二:正在出售第78张票

窗口二:正在出售第79张票

窗口二:正在出售第80张票

窗口二:正在出售第81张票

窗口二:正在出售第82张票

窗口二:正在出售第83张票

窗口二:正在出售第84张票

窗口二:正在出售第85张票

窗口二:正在出售第86张票

窗口二:正在出售第87张票

窗口二:正在出售第88张票

窗口二:正在出售第89张票

窗口二:正在出售第90张票

窗口二:正在出售第91张票

窗口二:正在出售第92张票

窗口二:正在出售第93张票

窗口二:正在出售第94张票

窗口二:正在出售第95张票

窗口二:正在出售第96张票

窗口二:正在出售第97张票

窗口三:正在出售第98张票

窗口一:正在出售第99张票

窗口二:正在出售第100张票
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 安全