第一种方式:继承Thread类
步骤:1、定义类继承Thread
2、覆写Threa类的run方法。 自定义代码放在run方法中,让线程运行
3、调用线程的star方法,
该线程有两个作用:启动线程,调用run方法。
代码示例:
1 class Test extends Thread 2 { 3 //private String name; 4 Test(String name) 5 { 6 //this.name = name; 7 super(name); 8 } 9 public void run() 10 { 11 for(int x=0; x<60; x++) 12 { 13 System.out.println((Thread.currentThread()==this)+"..."+this.getName()+" run..."+x); //Thread.currentThread():获取当前线程对象 14 } 15 } 16 17 } 18 19 20 class ThreadTest 21 { 22 public static void main(String[] args) 23 { 24 Test t1 = new Test("one---"); 25 Test t2 = new Test("two+++"); 26 t1.start(); 27 t2.start(); 28 // t1.run(); 29 // t2.run(); 30 31 for(int x=0; x<60; x++) 32 { 33 System.out.println("main....."+x); 34 } 35 } 36 }
第二种方式:实现Runnable接口
步骤:1、定义类实现Runnable接口
2、覆盖Runnable接口中的run方法,运行的代码放入run方法中。
3、通过Thread类建立线程对象。
4、将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
因为,自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象
5、调用Thread类的start方法开启线程并调用Runnable接口子类的run方法
代码示例:卖票程序,多个窗口同时卖票
1 class Ticket implements Runnable 2 { 3 private int tick = 100; 4 public void run() 5 { 6 while(true) 7 { 8 if(tick>0) 9 { 10 System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--); 11 } 12 } 13 } 14 } 15 16 17 class TicketDemo 18 { 19 public static void main(String[] args) 20 { 21 22 Ticket t = new Ticket(); 23 24 Thread t1 = new Thread(t);//创建了一个线程; 25 Thread t2 = new Thread(t);//创建了一个线程; 26 Thread t3 = new Thread(t);//创建了一个线程; 27 Thread t4 = new Thread(t);//创建了一个线程; 28 t1.start(); 29 t2.start(); 30 t3.start(); 31 t4.start(); 32 } 33 }
两种方式的区别:
第二种方式好处:避免了单继承的局限性。比如当一个student类继承了person类,再需继承其他的类时就不能了,所以在定义线程时,建议使用第二种方式。
解决多线程安全性问题:1、同步代码块
2、同步函数:锁为this
3、静态同步函数: 锁为Class对象:类名.class