使用同步代码块解决线程安全问题
package A_ShangGuiGu.Thread.ThreadDemo;标签:同步,Thread,代码,chepiao,线程,new,共享 From: https://www.cnblogs.com/zhazhawei906/p/16816784.html
/**
* 例子:三个窗口买票,使用实现Runnable接口的方法。
* 1.出现的问题:卖票过程中出现了重票,错票的问题。——————————》线程的安全问题
* 2.问题出现的原因:在一个线程操作共享数据的时候,还没有操作完成的时候,另一个线程也开始操作共享数据。
* 3.解决方法:当线程a在操作数据的时候,别的线程不能参与进来,直到线程a完成共享数据的操作后,线程b才可以开始操作共享数据,
* 这种情况下,即使线程a阻塞,其他的也不能操作。
* 4.在java中通过同步机制来解决线程的安全问题。
* 5.同步的方式,解决了线程的安全问题-----》好处
* 操作同步代码时,只能有一个线程参与,其他线程等待,相当于是一个单线程的过程,效率低。----局限性
* 6.在实现接口创建线程的方式中,我们可以使用this来充当锁(同步监视器)
* 7.在实现接口或者继承方式创建线程中,都可以使用(类名.class)来充当锁
* 方式一:同步代码块
* synchronized(同步监视器){
* //需要被同步的代码
* }
* 说明:操作共享数据的代码即为需要被同步的代码。
* 共享数据:多个线程共同处操作的数据或变量,比如chepiao就是共享数据
* 同步监视器:俗称锁。
* 任何一个类的对象都可以充当同步监视器
* 要求:多个线程必须使用同一把锁(同一个同步监视器、同一个对象)
*
* 方式二:同步方法
*/
class MaiPiao implements Runnable{
private int chepiao = 100;
Object obj = new Object();
@Override
public void run() {
while (true) {
synchronized (MaiPiao.class){
if (chepiao > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + ":" + chepiao);
chepiao--;
} else {
break;
}
}
}
}
}
public class ThreadWindowTest {
public static void main(String[] args) {
MaiPiao maiPiao = new MaiPiao();
Thread t1 = new Thread(maiPiao);
Thread t2 = new Thread(maiPiao);
Thread t3 = new Thread(maiPiao);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}