package Test22_Demo.Demo07;/* @create 2020--12--15--10:32*//** * 使用第二种方式创建线程,原因是执行线程目标对象共享 * 顶一个卖票的线程执行目标对象 - 加锁 * * 演示synchronized可以修饰方法,被修饰的方法叫做同步方法 * 同时也支持修饰静态方法!!!,但是一旦修饰了静态方法以后,这个对象就不是this了 * * 静态对象锁 * * 当前案例中,我们使用对象锁对当前的这个Ticket加锁,目的是this是当前正在被调用的这个Ticket对象 * 不管是synchronized代码块中,还是封装的一个synchronized方法,都可以保证使用的是同一个锁对象 * */public class Ticket implements Runnable { //票数 - 静态方法不能调用非静态资源 private static int number = 100; //生命成员变量为定义锁对象 private Object lock = new Object(); //创建一个标记,让不同的人来执行不同的代码块 private int x = 0; @Override public void run() { while (true) { //进行取余的运算,模拟买票的人 if (x % 2 == 0) { //把当前这个被调用的对象给锁住 synchronized (Ticket.class) { //线程暂停 try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } //如果有票就卖 if (number > 0) { String threadName = Thread.currentThread().getName(); System.out.println(threadName + "正在销售第"+(number--) + "张票"); } } } else { //调用sell方法 - 静态同步方法 //sell(); Ticket.sell(); } //当票数等于0,就表示没有票了 if (number <= 0) { break; } x++;//为了改变x的值,从而继续对2进行取余 } } //封装一个方法,用于定义同步买票 - 同步方法 public static synchronized void sell() { //需要加锁的逻辑放到一个方法中 try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } //有票就卖 if (number > 0) { String threadName = Thread.currentThread().getName(); System.out.println(threadName + "正在销售第"+(number--) + "张票"); } }}
package Test22_Demo.Demo07;/* @create 2020--12--15--10:44*//** * 测试线程 */public class ThreadDemo { public static void main(String[] args) { //实例化目标 Ticket ticket = new Ticket(); //使用该买票的目标创建多个程序 Thread thread1 = new Thread(ticket, "Jack"); Thread thread2 = new Thread(ticket, "Rose"); Thread thread3 = new Thread(ticket, "Tom"); //启动多个线程 thread1.start(); thread2.start(); thread3.start(); }}