多线程-同步代码块(同步的好处和弊端以及同步的前提条件)

  1 package multithread.test;
  2 
  3 import com.sun.org.apache.bcel.internal.generic.NEW;
  4 
  5 /*
  6  * 卖票
  7  */
  8 
  9 
 10 /*
 11  * 线程安全问题产生的原因:
 12  * 1,多个线程在操作共享的数据。
 13  * 2,操作共享数据的线程代码有多条。
 14  * 
 15  * 当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算。
 16  * 就会导致线程安全问题的产生。
 17  * 
 18  * 
 19  * 解决思路:
 20  * 就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候
 21  * 其他线程是不可以参与运算的。
 22  * 必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
 23  * 
 24  * 
 25  * 在java中,用同步代码块就可以解决这个问题。
 26  * 
 27  * 同步代码块的格式:
 28  * synchronize(对象){
 29  *         需要被同步的代码块
 30  * }
 31  * 同步代码块的好处:解决了线程的安全问题。
 32  * 
 33  * 
 34  * 同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。
 35  * 
 36  * 同步的前提:必须有多个线程并使用同一个锁。
 37  * 
 38  * 
 39  * 
 40  */
 41 
 42 
 43 class Ticket implements Runnable {//extends Thread {
 44     private /*static*/ int num = 100;//静态是可以的,根据实际看,有可能是这个线程负责这种100张,另一个线程时另一种票100张
 45     Object obj =  new Object();
 46     public void run() /*throws 不处理就抛,但是实现接口覆盖的方法,接口没有声明过异常,只能catch不能声明*/{
 47 //        Object obj =  new Object();//每个线程开启都会创建一个对象,就会有不同锁,会出错
 48         while(true) {
 49             synchronized (obj/*对象锁或者叫同步锁*/){
 50                 if (num>0) {
 51 //                    try {
 52 //                        Thread.sleep(10);//sleep方法有个抛出
 53 //                    } catch (InterruptedException e) {
 54 //                        // TODO: handle exception
 55 //                    }
 56 //                    //
 57                     System.out.println(Thread.currentThread().getName()+"....sale...."+ num--);
 58                 }
 59             }
 60             
 61             
 62         }
 63     }
 64 }
 65 
 66 public class TicketDemo {
 67 
 68     public static void main(String[] args) {
 69         // TODO Auto-generated method stub
 70         
 71         Ticket t = new Ticket();//创建一个线程任务对象。
 72         
 73         
 74         Thread t1 = new Thread(t);
 75         Thread t2 = new Thread(t);
 76         Thread t3 = new Thread(t);
 77         Thread t4 = new Thread(t);
 78 
 79         t1.start();
 80         t2.start();
 81         t3.start();
 82         t4.start();
 83         /*
 84         Ticket t1 = new Ticket();
 85         Ticket t2 = new Ticket();
 86         Ticket t3 = new Ticket();
 87         Ticket t4 = new Ticket();
 88         //只有100张,卖了400张,为什么?
 89         t1.start();
 90 //        t1.start();IllegalThreadStateException-无效线程状态异常是 runtime异常
 91 //        t1.start();
 92 //        t1.start();
 93         
 94         t2.start();
 95         t3.start();
 96         t4.start();
 97         */
 98         
 99         
100     }
101    //cmd 打印完1在前面 比如43打印在后面, cmd是应用程序,虚拟机也是一个应用程序,cpu也是在这两个中切换造成的
102 }
TicketDemo

 

posted @ 2021-11-06 17:18  doremi429  阅读(87)  评论(0编辑  收藏  举报