用之前学习的线程方法去写(有bug):
package com.ytzl.第3章.dmeo1多线程.two;
/*多线程之同步代码块*/
/*模拟网络抢票*/
public class one implements Runnable{
private int count=10;//记录抢票次数
private int num=0;//记录买到第几张票
public static void main(String[] args) {
one site = new one();
Thread p1 = new Thread(site,"携程");
Thread p2 = new Thread(site,"黄牛");
Thread p3 = new Thread(site,"支付");
System.out.println("*******开始抢票*******");
p1.start();
p2.start();
p3.start();
}
@Override
public void run() {
while (true){
//同步方法,一次只有一个线程能使用当前方法
//sale();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
//同步代码块,一次只有一个线程能使用代码块
if (count<=0) {
break;
}
num++;
count--;
System.out.println(Thread.currentThread().getName()+"抢到第"+num+"张票,剩余"+count+"张票!");
}
}
}
当我们去以之前的写法同时运行多个线程程序时,它们会同时去抢一个进程,会出现如下结果:
会出现多个线程抢到同一张票,这样就会减低一定的运行速度,我们需要在里边加入一个方法
synchronized(){};
去抢,它的作用是同步代码块,将我们需要执行的代码放入该方法即可,同一时刻只能有一个线程进入synchronized{}同步状态,当一个线程被同步的时候,其他线程代码同样是被锁定的,代码块锁定时,其他线程可以访问非同步代码,通俗的来讲就是当其中一个线程在执行这个状态时,其它线程则不能去执行,只能去执行下一个状态代码。
完善后的代码如下:
package com.ytzl.第3章.dmeo1多线程.two;
/*多线程之同步代码块*/
/*模拟网络抢票*/
public class one implements Runnable {
private int count = 10;//记录抢票次数
private int num = 0;//记录买到第几张票
public static void main(String[] args) {
one site = new one();
Thread p1 = new Thread(site, "携程");
Thread p2 = new Thread(site, "黄牛");
Thread p3 = new Thread(site, "支付");
System.out.println("*******开始抢票*******");
p1.start();
p2.start();
p3.start();
}
@Override
public void run() {
while (true) {
//同步方法,一次只有一个线程能使用当前方法
//sale();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
//同步代码块,一次只有一个线程能使用代码块
synchronized (this) {
/*
* 多线程在高并发访问同一资源的时候
* 同一时刻只能有一个线程进入synchronized同步状态
* 当一个线程被同步的时候,其他线程代码块同样是被锁定的
* 代码快锁定的,其他线程可以访问非同步代码
* */
if (count <= 0) {
break;
}
num++;
count--;
System.out.println(Thread.currentThread().getName() + "抢到第" + num + "张票,剩余" + count + "张票!");
}
}
}
}
运行结果如下: