第一种继承Thread类实现多线程
备注:启动线程调用start()方法而不是调用run()方法,且每个对象只能调用一次start方法,否则会报错IllegalThreadStateException
package demo.test; public class demo1 { public static void main(String[] args) { Student s1 = new Student("s1"); Student s2 = new Student("s2"); s1.start(); s2.start(); } } class Student extends Thread{ private String name; public Student(String name) { this.name = name; } public void run(){ for (int i = 0; i < 10; i++) { System.out.println("name:"+this.name+"\ti:"+i); } } }
//result:
name:s1 i:0
name:s2 i:0
name:s2 i:1
name:s2 i:2
name:s2 i:3
name:s2 i:4
name:s2 i:5
name:s2 i:6
name:s2 i:7
name:s2 i:8
name:s1 i:1
name:s1 i:2
name:s1 i:3
name:s1 i:4
name:s1 i:5
name:s1 i:6
name:s1 i:7
name:s1 i:8
name:s1 i:9
name:s2 i:9
第二种实现runnable接口重写run方法实现多线程
备注:Runnable与Thread的区别:
Runnable可以避免Thread单继承的局限,能够实现共享程序的概念,可以多线程一起卖10张票,而Thread的话就是各自卖10张票了
package demo.test; public class Demo2 { public static void main(String[] args) { MyThread m1 = new MyThread(); new Thread(m1).start(); new Thread(m1).start(); //匿名内部类创建 new Thread(new Runnable() { @Override public void run() { System.out.println("hello java"); } }).start(); } } class MyThread implements Runnable { private int ticket=10; @Override public void run() { while (ticket>0){ System.out.println("卖出票"+ticket--); } } }
调用start()和调用run()方法的区别
start() 能够启动新的线程,start()内部调用了run方法 , 而直接调用run方法只是在原来的线程上调用
第三种实现callable接口重写call()方法实现多线程
备注:Runnable与Callable的区别:
Callable有返回值,能抛出异常,需要FutureTask实现类的支持,get()方法等待线程执行完后接收返回值
package demo.test; import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; public class demo3 { public static void main(String[] args) throws Exception{ FutureTask<String> task1 = new FutureTask<String>(new MyThread2()); new Thread(task1).start(); new Thread(task1).start(); System.out.println(task1.get()); } } class MyThread2 implements Callable<String>{ private int ticket=10; @Override public String call() throws Exception { while (ticket>0){ System.out.println("卖出票"+ticket--); } return "票卖完了"; } }