> 文档中心 > 多线程的创建

多线程的创建


创建方式一:继承Thread类创建多线程

public class 多线程_1创建 {    public static void main(String[] args) { //创建方式一 Thread t=new MyThread();//创建MyThread线程对象 //直接调run()方法会被当成普通方法执行,此时相当于还是单线程执行, // 所以需要调用start()方法启动多线程 t.start();//调用start()方法启动线程(实际执行的还是run()方法) //注意:子线程一定要放在主线程之前,不然先跑主线程还是会被当做是单线程 for (int i = 0; i < 6; i++) {     System.out.println("主线程执行:"+i); }    }}//继承Thread类创建多线程,优点:代码简单。// 缺点:线程类已经继承Thread类,无法继承其他类,不利于扩展 class MyThread extends Thread{//继承Thread类,重写其中的方法即可实现多线程    //重写run()方法    public void run(){ for (int i = 0; i < 6; i++) {     System.out.println("子线程执行:"+i); }    }}

创建方式二:实现Runnable接口

class r{    //创建方式二    public static void main(String[] args) { //创建一个任务对象 Runnable r=new MyRunnable(); //把任务对象交给Thread处理 Thread t=new Thread(r); t.start();//调用start()方法启动线程(实际执行的还是run()方法) //注意:子线程一定要放在主线程之前,不然先跑主线程还是会被当做是单线程 for (int i = 0; i < 5; i++) {     System.out.println("主线程执行:"+i); }    }    }    //优点:只是实现接口,可以继续继承类和实现接口,扩展性强    // 缺点:多一层对象包装,如果线程有执行结果,是不可以直接返回的class MyRunnable implements Runnable{//实现Runnable接口,重写其中的方法即可实现多线程    public void run(){ for (int i = 0; i < 5; i++) {     System.out.println("子线程执行:"+i); }    }}

创建方式二的另一种语法形式: 

class r_2{    //实现Runnable接口,用匿名内部类的方式(另一种语法形式)    public static void main(String[] args) { //原始形态:// Runnable r=new Runnable() {//     @Override//     public void run() {//  for (int i = 0; i {     for (int i = 0; i < 5; i++) {  System.out.println("子线程执行:"+i);     } }).start(); for (int i = 0; i < 5; i++) {     System.out.println("主线程执行:"+i); }    }}

 小案例:

class 案例_售票{    //四个窗口同时售买100张票    public static void main(String[] args) { TicketWindow tw=new TicketWindow();//创建TicketWindow实例化对象 new Thread(tw,"窗口1").start();//创建线程对象并命名为窗口1,开启线程 new Thread(tw,"窗口2").start(); new Thread(tw,"窗口3").start(); new Thread(tw,"窗口4").start();    }}class TicketWindow implements Runnable{    private int tickets=100;    public void run(){ while(true){     if(tickets>0) {  Thread t = Thread.currentThread();//获取当前线程  String t_name = t.getName();//获取当前线程名字  System.out.println(t_name + "正在发售第\t" + tickets-- + "\t张票");//票售出后--,不然永远卖不完     }     if(tickets==0){  break;     } }    }}

 前两种创建方式都有一个共同的缺点,那就是不能返回线程执行结果

于是便有了创建方式三:实现Callable接口

import java.util.concurrent.Callable;import java.util.concurrent.FutureTask;class 创建_返回结果{    public static void main(String[] args)throws Exception{ //创建Callable任务对象 Callable c=new MyCallable(100); //把Callable任务对象交给FutrueTask对象 //FutrueTask对象作用1:是Runnable对象(实现了Runnable接口),可以交给Thread了 //FutrueTask对象作用2:可以在线程执行完毕后调用get方法得到线程执行完毕的结果 FutureTaskf1=new FutureTask(c); //交给线程处理 Thread t1=new Thread(f1); t1.start();//启动线程1 Callable c2=new MyCallable(200); FutureTaskf2=new FutureTask(c2); Thread t2=new Thread(f2); t2.start();//启动线程2 //如果f1任务没有执行完毕,那么这里的代码会等待,直到线程1跑完才提取结果 String str1=f1.get(); System.out.println("第一个线程执行结果为:"+str1); //如果f2任务没有执行完毕,那么这里的代码会等待,直到线程2跑完才提取结果 String str2=f2.get(); System.out.println("第二个线程执行结果为:"+str2);    }}//定义一个任务类,实现Callable接口,应该声明线程任务结束后返回的结果的数据类型class MyCallable implements Callable {    //   v(泛型)    private int n;    public MyCallable(int n) { this.n = n;    }    //重写call方法    //案例:加法    public String call() throws Exception { int sum = 0; for (int i = 1; i <=n; i++) {     sum += i; } return "子线程执行结果为:" + sum;    }}

三种创建多线程方式的优缺点 :