一、继承Thread来创建线程
package com.xu.chap2;
/**
* 目的:实现火车站卖票系统(第一种创建线程的方式)
*
*/
//第一种方式直接继承Thread来创建线程
class T1 extends Thread
{
//加static的原因是:每次new一个对象出来,该对象就会有一个tickets属性,这样的话就相当于卖2倍票数,当然错误
private static int tickets = 10;
//加static的原因是:确定同步的是同一个str,原理同上。
static String str = new String ("start");
//重写run方法
public void run()
{
while(true)
{
synchronized(str)//同步代码块
{
if(tickets > 0)
{
System.out.printf("%s线程正在运行,第%d张票正在出售\n",Thread.currentThread().getName(),tickets);
tickets--;
}
}
}
}
}
public class Ticket_1
{
public static void main(String[] args)
{
//两个对象,两个线程
T1 tic1 = new T1();
T1 tic2 = new T1();
tic1.start();
tic2.start();
}
}
运行结果:
二、使用Runnable接口创建线程
package com.xu.chap2;
/**
* 目的:实现火车站的卖票系统(第二种创建线程的方式)
*/
//创建线程的第二种方式
class T2 implements Runnable {
/*相较于第一种创建线程的方式,
* 这里不需要加static,
* 因为该创建方式是同一个对象里面的不同线程,
* 第一种创建方式是不同对象的不同线程,
*/
private int tickets = 10;
String str = new String("start");
//重写run
public void run() {
while (true) {
//同步代码块
synchronized (str) {
if (tickets > 0) {
System.out.printf("%s线程正在运行,正在卖出剩余的第%d张票\n", Thread.currentThread().getName(), tickets);
/*
* 调用Thread类中的currentThread()方法到达当前线程,再通过getName()方法获取当前线程的名称
*/
tickets--;
}
}
}
}
}
public class Ticket_2 {
public static void main(String[] args) {
//构建T2的对象
T2 tt = new T2();
//用同一个对象构造里面的两个线程
Thread t1 = new Thread(tt);
Thread t2 = new Thread(tt);
t1.setName("南京站");
t2.setName("南京南站");
//开启线程
t1.start();
t2.start();
}
}
运行结果:
今天到此为止,我们下回再见!