1 /** 2 * 2019年8月8日16:05:05 3 * 目的:实现火车站卖票系统(第一种创建线程的方式) 4 * @author 张涛 5 * 6 */ 7 8 //第一种方式直接继承Thread来创建线程 9 class T1 extends Thread 10 { 11 //加static的原因是:每次new一个对象出来,该对象就会有一个tickets属性,这样的话就相当于卖2倍票数,当然错误 12 private static int tickets = 1000; 13 //加static的原因是:确定同步的是同一个str,原理同上。 14 static String str = new String ("start"); 15 //重写run方法 16 public void run() 17 { 18 while(true) 19 { 20 synchronized(str)//同步代码块 21 { 22 if(tickets > 0) 23 { 24 System.out.printf("%s线程正在运行,第%d张票正在出售 ",Thread.currentThread().getName(),tickets); 25 tickets--; 26 } 27 } 28 29 } 30 31 } 32 } 33 34 public class Ticket_1 35 { 36 public static void main(String[] args) 37 { 38 //两个对象,两个线程 39 T1 tic1 = new T1(); 40 T1 tic2 = new T1(); 41 42 tic1.start(); 43 tic2.start(); 44 } 45 }
1 /** 2 * 2019年8月8日17:04:45 3 * 目的:实现火车站的卖票系统(第二种创建线程的方式) 4 * @author 张涛 5 * 6 */ 7 8 //创建线程的第二种方式 9 class T2 implements Runnable 10 { 11 /*相较于第一种创建线程的方式, 12 * 这里不需要加static, 13 * 因为该创建方式是同一个对象里面的不同线程, 14 * 第一种创建方式是不同对象的不同线程, 15 */ 16 private int tickets = 10000; 17 String str = new String ("start"); 18 19 //重写run 20 public void run() 21 { 22 while(true) 23 { 24 //同步代码块 25 synchronized (str) 26 { 27 if(tickets > 0) 28 { 29 System.out.printf("%s线程正在运行,正在卖出剩余的第%d张票 ",Thread.currentThread().getName(),tickets); 30 /* 31 * 调用Thread类中的currentThread()方法到达当前线程,再通过getName()方法获取当前线程的名称 32 */ 33 tickets--; 34 } 35 } 36 } 37 } 38 } 39 40 public class Ticket_2 41 { 42 public static void main(String[] args) 43 { 44 //构建T2的对象 45 T2 tt = new T2(); 46 //用同一个对象构造里面的两个线程 47 Thread t1 = new Thread (tt); 48 Thread t2 = new Thread (tt); 49 t1.setName("南京站"); 50 t2.setName("南京南站"); 51 52 //开启线程 53 t1.start(); 54 t2.start(); 55 } 56 }