A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始


  1. 判断一个程序是否会有线程安全问题的标准:
  2.           * A:是否是多线程环境
  3.           * B:是否有共享数据
  4.           * C:是否有多条语句操作共享数据


  5. * 接下来才是我们要想想如何解决问题呢?
  6. * A和B的问题我们改变不了,我们只能想办法去把C改变一下。
  7. * 思想:
  8. *                 把多条语句操作共享数据的代码给包成一个整体,让某个线程在执行的时候,别人不能来执行。
  9. * 问题是我们不知道怎么包啊?其实我也不知道,但是Java给我们提供了:同步机制。
  10. *
  11. * 同步代码块://这里的对象可以是任意对象
  12. *                 synchronized(对象){
  13. *                         需要同步的代码;
  14. *                 }
  15. *
  16. *                 A:对象是什么呢?
  17. *                         我们可以随便创建一个对象试试。
  18.             处理线程安全问题的方法:
  19.                 Object obj = new Object();
  20.                         synchronized(obj){
  21.                         需要同步的代码;
  22.                 }
  23. *                 B:需要同步的代码是哪些呢?
  24. *                         把多条语句操作共享数据的代码的部分给包起来
  25. *
  26. *                 注意:
  27. *                         同步可以解决安全问题的根本原因就在那个对象上。该对象如同锁的功能。
  28. *                         多个线程必须是同一把锁。
  29. */
  30. 以火车卖票为例:
  31. package cn.itcast_10;
  32. /*
  33. * 举例:
  34. *                 火车上厕所。
  35. *
  36. * 同步的特点:
  37. *                 前提:
  38. *                         多个线程
  39. *                解决问题的时候要注意:
  40. *                        多个线程使用的是同一个锁对象
  41. * 同步的好处
  42. *                同步的出现解决了多线程的安全问题。
  43. * 同步的弊端
  44. *                当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低    程序的运行效率。
  45. */
  46. public class SellTicketDemo {
  47.         public static void main(String[] args) {
  48.                 // 创建资源对象
  49.                 SellTicket st = new SellTicket();
  50.                 // 创建三个线程对象
  51.                 Thread t1 = new Thread(st, "窗口1");
  52.                 Thread t2 = new Thread(st, "窗口2");
  53.                 Thread t3 = new Thread(st, "窗口3");
  54.                 // 启动线程
  55.                 t1.start();
  56.                 t2.start();
  57.                 t3.start();
  58.         }
  59. }
  60. package cn.itcast_10;
  61. public class SellTicket implements Runnable {
  62.         // 定义100张票
  63.         private int tickets = 100;
  64.         // 定义同一把锁
  65.         private Object obj = new Object();
  66.         @Override
  67.         public void run() {
  68.                 while (true) {
  69.                         // t1,t2,t3都能走到这里
  70.                         // 假设t1抢到CPU的执行权,t1就要进来
  71.                         // 假设t2抢到CPU的执行权,t2就要进来,发现门是关着的,进不去。所以就等着。
  72.                         // 门(开,关)
  73.                         synchronized (obj) { // 发现这里的代码将来是会被锁上的,所以t1进来后,就锁了。(关)
  74.                                 if (tickets > 0) {
  75.                                         try {
  76.                                                 Thread.sleep(100); // t1就睡眠了
  77.                                         } catch (InterruptedException e) {
  78.                                                 e.printStackTrace();
  79.                                         }
  80.                                         System.out.println(Thread.currentThread().getName()
  81.                                                         + "正在出售第" + (tickets--) + "张票 ");
  82.                                         //窗口1正在出售第100张票
  83.                                 }
  84.                         } //t1就出来可,然后就开门。(开)
  85.                 }
  86.         }
  87. }

复制代码

1 个回复

倒序浏览
收藏; ,,,,,,,,,
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马