第一种方式:继承Thread类安全
步骤:一、定义类继承Thread多线程
二、覆写Threa类的run方法。 自定义代码放在run方法中,让线程运行函数
三、调用线程的star方法,this
该线程有两个做用:启动线程,调用run方法。spa
代码示例:线程
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接口code
步骤:一、定义类实现Runnable接口对象
二、覆盖Runnable接口中的run方法,运行的代码放入run方法中。blog
三、经过Thread类创建线程对象。继承
四、将Runnable接口的子类对象做为实际参数传递给Thread类的构造函数。
由于,自定义的run方法所属的对象是Runnable接口的子类对象。因此要让线程去指定指定对象的run方法。就必须明确该run方法所属对象
五、调用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类,再需继承其余的类时就不能了,因此在定义线程时,建议使用第二种方式。
解决多线程安全性问题:一、同步代码块
二、同步函数:锁为this
三、静态同步函数: 锁为Class对象:类名.class