使用同步代码块解决线程安全问题

使用同步代码块解决线程安全问题

package A_ShangGuiGu.Thread.ThreadDemo;

/**
* 例子:三个窗口买票,使用实现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();
  }
}
 
posted @ 2022-10-22 17:42  zhazhawei906  阅读(141)  评论(0)    收藏  举报