1. package Test22_Demo.Demo06;/*
    2. @create 2020--12--15--10:32
    3. */
    4. /**
    5. * 使用第二种方式创建线程,原因是执行线程目标对象共享
    6. * 顶一个卖票的线程执行目标对象 - 加锁
    7. *
    8. * 演示synchronized可以修饰方法,被修饰的方法叫做同步方法
    9. *
    10. * 当前案例中,我们使用对象锁对当前的这个Ticket加锁,目的是this是当前正在被调用的这个Ticket对象
    11. * 不管是synchronized代码块中,还是封装的一个synchronized方法,都可以保证使用的是同一个锁对象
    12. *
    13. */
    14. public class Ticket implements Runnable {
    15. //票数
    16. private int number = 100;
    17. //生命成员变量为定义锁对象
    18. private Object lock = new Object();
    19. //创建一个标记,让不同的人来执行不同的代码块
    20. private int x = 0;
    21. @Override
    22. public void run() {
    23. while (true) {
    24. //进行取余的运算,模拟买票的人
    25. if (x % 2 == 0) {
    26. //把当前这个被调用的对象给锁住
    27. synchronized (this) {
    28. //线程暂停
    29. try {
    30. Thread.sleep(500);
    31. } catch (InterruptedException e) {
    32. e.printStackTrace();
    33. }
    34. //如果有票就卖
    35. if (number > 0) {
    36. String threadName = Thread.currentThread().getName();
    37. System.out.println(threadName + "正在销售第"+(number--) + "张票");
    38. }
    39. }
    40. } else {
    41. //调用sell方法 - 同步方法
    42. this.sell();
    43. }
    44. //当票数等于0,就表示没有票了
    45. if (number <= 0) {
    46. break;
    47. }
    48. x++;//为了改变x的值,从而继续对2进行取余
    49. }
    50. }
    51. //封装一个方法,用于定义同步买票 - 同步方法
    52. public synchronized void sell() {
    53. //需要加锁的逻辑放到一个方法中
    54. try {
    55. Thread.sleep(20);
    56. } catch (InterruptedException e) {
    57. e.printStackTrace();
    58. }
    59. //有票就卖
    60. if (number > 0) {
    61. String threadName = Thread.currentThread().getName();
    62. System.out.println(threadName + "正在销售第"+(number--) + "张票");
    63. }
    64. }
    65. }
    1. package Test22_Demo.Demo06;/*
    2. @create 2020--12--15--10:44
    3. */
    4. /**
    5. * 测试线程
    6. */
    7. public class ThreadDemo {
    8. public static void main(String[] args) {
    9. //实例化目标
    10. Ticket ticket = new Ticket();
    11. //使用该买票的目标创建多个程序
    12. Thread thread1 = new Thread(ticket, "Jack");
    13. Thread thread2 = new Thread(ticket, "Rose");
    14. Thread thread3 = new Thread(ticket, "Tom");
    15. //启动多个线程
    16. thread1.start();
    17. thread2.start();
    18. thread3.start();
    19. }
    20. }