创建新执行线程有两种方式:
1.继承Thread类,覆写run();将线程要运行的代码存放在该run()方法中,然后调用 Thread类中的start();方法开启线程。
2.实现Runnable接口,覆写run();将线程要运行的代码存放在该run()方法中,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数,调用Thread类中的
start();方法开启线程并调用Runnable接口子类的run()方法。
一、继承Thread类的方式:
1 public class Ticket extends Thread { 2 private static int ticket = 100; 3 // private int ticket = 100; 此处必须用静态成员变量,如果是非静态成员变量 4 // 当new一个线程对象时就会产生一个全新的ticket,而我们需要的是共享ticket的值,所以用静态的 5 6 public void run() { 7 while (ticket > 0 && ticket <= 100) { 8 System.out.println(currentThread().getName() + "..." + ticket); 9 ticket--; 10 } 11 12 } 13 14 }
1 public class TicketTest { 2 3 public static void main(String[] args) { 4 Ticket t1=new Ticket(); 5 Ticket t2=new Ticket(); 6 Ticket t3=new Ticket(); 7 t1.start(); 8 t2.start(); 9 t3.start(); 10 } 11 12 13 }
二、实现Runnable接口方式
public class Ticket implements Runnable{ private int ticket=100;//此处不用加静态因为调用时只实例化了一个对象。 @Override public void run() { while(ticket>0 && ticket<=100){ // System.out.println(Thread.currentThread().getName()+"..."+ticket); // ticket--; 此处会出现线程安全问题,需要使用同步代码块。 synchronized (this) { System.out.println(Thread.currentThread().getName()+"..."+ticket); ticket--; } } } }
1 public class TicketTest { 2 3 public static void main(String[] args) { 4 Ticket t=new Ticket(); 5 Thread t1=new Thread(t); 6 Thread t2=new Thread(t); 7 Thread t3=new Thread(t); 8 t1.start(); 9 t2.start(); 10 t3.start(); 11 12 } 13 14 15 }
实现方式的好处:避免了单继承的局限性,在定义线程时建议使用实现方式
总结:
实现Runnable接口和继承Thread方法的区别 :
实现方式:线程代码存放在接口子类的run方法中
继承方式:线程代码存放在Thread子类的run方法中