1、第一种:自定义一个类,继承Thread类
实现方式:1)自定义如MyThread类,继承自Thread类
2)重写Thread类中的run()方法
3)创建MyThread类对象,分别启动线程 4)代码举例:package Thread_method_one_extends;
/*
* 模拟电影卖票过程
* */
//第一种方式:继承Thread类
public class SellTicket extends Thread {
//定义100张票
//static表示静态,公有
private static int tickets = 100;
//重写run()方法
@Override
public void run() {
//模拟一直有票
while(true) {
if(tickets > 0) {
System.out.println(getName()+"正在出售第"+(tickets--)+"张票");
}
}
}
}
package Thread_method_one_extends;
public class SellTicket_test {
public static void main(String[] args) {
//创建三个子线程,来代表三个窗口
SellTicket s1 = new SellTicket();
SellTicket s2 = new SellTicket();
SellTicket s3 = new SellTicket();
//设置线程名称
s1.setName("窗口1");
s2.setName("窗口2");
s3.setName("窗口3");
//启动线程
s1.start();
s2.start();
s3.start();
}
}
2、第二种:自定义一个类,实现Runnable接口
实现方式:1)自定义如MyRunnable类,实现Runnable接口
2)实现接口的run()方法
3)创建MyRunnable类对象,创建Thread类对象,将MyRunnable类对象作为参数传递,分别启动线程
4)代码举例
package Thread_method_two_Runnable;
/*
* 模拟电影卖票过程
* */
//第一种方式:继承Thread类
public class SellTicket implements Runnable{
//定义100张票
//static表示静态,公有
private int tickets = 100;
//重写run()方法
@Override
public void run() {
//模拟一直有票
while(true) {
if(tickets > 0) {
System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
}
}
}
}
package Thread_method_two_Runnable;
public class SellTicket_test {
//第二种方式:加入延迟操作
public static void main(String[] args) {
//创建资源类对象
SellTicket st = new SellTicket();
//创建线程类对象
Thread t1 = new Thread(st,"窗口1");
Thread t2 = new Thread(st,"窗口2");
Thread t3 = new Thread(st,"窗口3");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
3、两种方式的需要注意的地方和异同:
1)启动线程需调用start()方法,不可调用run()方法,因为调用run()方法相当于调用了一个人普通的方法,无法实现其随机性。
2)一个线程不要连续启动,负责会出现非法线程状态异常
3)通常第二种方法是要优于第一方法的,因为第一种方法使用继承,具有局限性。第二种方法更符合Java面向对象的设计原则,面向接口编程。符合数据分离原则:将代码的实现和资源对象分离开来。