有4种方式可以用来创建线程:
1、继承Thread类(真正意义上的线程类),是Runnable接口的实现。
2、实现Runnable接口,并重写里面的run方法。
3、使用Executor框架创建线程池。Executor框架是juc里提供的线程池的实现。
4、实现callable接口,重写call方法
调用线程的start():启动此线程;调用相应的run()方法
继承于Thread类的线程类,可以直接调用start方法启动线程(使用static也可以实现资源共享).一个线程(对象)只能够执行一次start(),而且不能通过Thread实现类对象的run()去启动一个线程。
实现Runnable接口的类需要再次用Thread类包装后才能调用start方法。(三个Thread对象包装一个类对象,就实现了资源共享)。
线程的使用的话,注意锁和同步的使用。(多线程访问共享资源容易出现线程安全问题)
一般情况下,常见的是第二种。
* Runnable接口有如下好处:
*①避免单继承的局限,一个类可以继承多个接口。
*②适合于资源的共享
1、继承Thread
//1.创建一个继承于Thread的子类 class DemoThread extends Thread{ public void run(){ //2.重写Thread类的run()方法,方法内实现子线程要完成的功能 for(int i=1;i<=10;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } } } public class TestThread { public static void main(String[] args) { //3.创建一个子类的对象 DemoThread s = new DemoThread(); //4.调用线程的start():启动此线程;调用相应的run()方法 s.start(); //主线程继续执行以下 for(int i=1;i<=10;i++){ System.out.println(i); } } }
/*Thread的常用方法: * 1.start():启动线程并执行相应的run()方法 * 2.run():子线程要执行的代码放入run()方法中 * 3.currentThread():静态的,调用当前的线程 * 4.getName():获取此线程的名字 * 5.setName():设置此线程的名字 * 6.yield():调用此方法的线程释放当前cpu的执行权 * 7.join():是调用线程等待该线程完成后,才能继续用下运行 * 8.isAlive():判断当前线程是否还存活 * 9.sleep(long 1):显式的让当前线程睡眠1毫秒 * 10.线程通信: wait() notify() notifyAll() * * 设置线程优先级 * getPriority():返回线程优先值 * setPriority(int newPriority):改变线程优先级 * */
一个多线程小demo:

/*创建两个子线程,让其中一个输出1-100之间的偶数,另一个输出1-100之间的奇数*/ class Thread1 extends Thread{ public void run(){ for(int i=1;i<=100;i++){ if(i%2==0) System.out.println(Thread.currentThread().getName()+":"+i); } } } class Thread2 extends Thread{ public void run(){ for(int i=1;i<=100;i++){ if(i%2!=0) System.out.println(Thread.currentThread().getName()+":"+i); } } } public class TestThread { public static void main(String[] args) { Thread1 s1 = new Thread1(); Thread2 s2 = new Thread2(); s1.start(); s2.start(); //继承于Thread类的匿名类的对象 // new Thread(){ // public void run(){ // for(int i=1;i<=100;i++){ // if(i%2==0) // System.out.println(Thread.currentThread().getName()+":"+i); // } // } // }.start(); // // new Thread(){ // public void run(){ // for(int i=1;i<=100;i++){ // if(i%2!=0) // System.out.println(Thread.currentThread().getName()+":"+i); // } // } // }.start(); } }
2、通过实现Runnable接口的方式
/*创建两个子线程,输出1-100之间的偶数*/ class Thread1 implements Runnable{ public void run(){ for(int i=1;i<=100;i++){ if(i%2==0) System.out.println(Thread.currentThread().getName()+":"+i); } } }public class TestThread { public static void main(String[] args) { Thread1 s = new Thread1(); //要想启动一个线程,必需调用start() Thread t1 = new Thread(s); t1.start(); Thread t2 = new Thread(s); t2.start(); } }
Thread与Runnable
1、联系:public class Thread implements Runnable
2、哪个方式好?实现的方式优于继承的方式
1) 避免了Java的单继承的局限性
2) 如果多个线程要操作同一份资源(或数据),更适合使用实现的方式
参考与推荐: