A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 四川男人 中级黑马   /  2014-4-3 22:37  /  1301 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

JAVA实现多线程有两种方式:
一种是继承Thread类并重写run()方法;具体实现是在main()函数中创建Thread子类对象,并调用start()方法开启线程和run()方法。
另一种是实现Runnable接口,实现run()方法;至于具体实现我总是没搞懂。
                         各位前辈高人给点儿指教吧,通俗易懂一点儿就好!!!!!!!!!

5 个回复

倒序浏览
一个类如果需要具备多线程的能力,也可以通过实现java.lang.Runnable接口进行实现。按照Java语言的语法,一个类可以实现任意多个接口,所以该种实现方式在实际实现时的通用性要比前面介绍的方式好一些。

  1.    /**

  2. * 测试类

  3. */

  4. public class Test2 {

  5.          public static void main(String[] args) {

  6.                    //创建对象

  7.                    MyRunnable mr = new MyRunnable();

  8.                    Thread t = new Thread(mr);

  9.                    //启动

  10.                    t.start();

  11.                    try{

  12.                             for(int i = 0;i < 10;i++){

  13.                                      Thread.sleep(1000);

  14.                                      System.out.println("main:" + i);

  15.                             }

  16.                    }catch(Exception e){}

  17.          }

  18. }

  19.          /**

  20. * 使用实现Runnable接口的方式实现多线程

  21. */

  22. public class MyRunnable implements Runnable {

  23.          public void run() {

  24.                    try{

  25.                             for(int i = 0;i < 10;i++){

  26.                                      Thread.sleep(1000);

  27.                                      System.out.println("run:" + i);

  28.                             }

  29.                    }catch(Exception e){}

  30.          }

  31. }
复制代码


该示例代码实现的功能和前面实现的功能相同。在使用该方式实现时,使需要实现多线程的类实现Runnable,实现该接口需要覆盖run方法,然后将需要以多线程方式执行的代码书写在run方法内部或在run方法内部进行调用。

在需要启动线程的地方,首先创建MyRunnable类型的对象,然后再以该对象为基础创建Thread类的对象,最后调用Thread对象的start方法即可启动线程。代码如下:

//创建对象

MyRunnable mr = new MyRunnable();

Thread t = new Thread(mr);

//启动

         t.start();

在这种实现方式中,大部分和前面介绍的方式类似,启动的代码稍微麻烦一些。这种方式也是实现线程的一种主要方式。

评分

参与人数 1技术分 +1 收起 理由
枫儿 + 1 赞一个!

查看全部评分

回复 使用道具 举报
  1. class Ticket implements Runnable//extends Thread
  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. class  TicketDemo
  16. {
  17.         public static void main(String[] args)
  18.         {

  19.                 Ticket t = new Ticket();

  20.                 Thread t1 = new Thread(t);//创建了一个线程;
  21.                 Thread t2 = new Thread(t);//创建了一个线程;
  22.                 Thread t3 = new Thread(t);//创建了一个线程;
  23.                 Thread t4 = new Thread(t);//创建了一个线程;
  24.                 t1.start();
  25.                 t2.start();
  26.                 t3.start();
  27.                 t4.start();


  28.                 /*
  29.                 Ticket t1 = new Ticket();
  30.                 //Ticket t2 = new Ticket();
  31.                 //Ticket t3 = new Ticket();
  32.                 //Ticket t4 = new Ticket();

  33.                 t1.start();
  34.                 t1.start();
  35.                 t1.start();
  36.                 t1.start();
  37.                 */

  38.         }
  39. }
复制代码
创建线程的第二种方式:实现Runable接口
步骤:
1,定义类实现Runnable接口
2,覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。
3,通过Thread类建立线程对象。
4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
        为什么要将Runnable接口的子类对象传递给Thread的构造函数。
        因为,自定义的run方法所属的对象是Runnable接口的子类对象。
        所以要让线程去执行指定对象的run方法。就必须明确该run方法所属对象。
5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
实现方式和继承方式有什么区别呢?
实现方式好处:避免了单继承的局限性。
在定义线程时,建立使用实现方式。
两种方式区别:
继承Thread:线程代码存放Thread子类run方法中。
实现Runnable,线程代码存在接口的子类的run方法。

评分

参与人数 1技术分 +1 收起 理由
枫儿 + 1 赞一个!

查看全部评分

回复 使用道具 举报
还有一种方法就是写一个匿名内部类,匿名内部类是一种特殊的局部内部类,因为有时候为了方便就不用再外面写它的类了,直接在内部写一个匿名的thread的子类,具体实现代码看下面:package 多线程;
//匿名内部类的方式创建线程
public class ThreadDemo1 {
       
        public static void main(String arr[]){
        Thread thread=new Thread(){
               
                        public void run() {
                                while (true) {
                                        System.err.println("1"+Thread.currentThread().getId()+Thread.currentThread().getName());
                                       
                                }
                        }
               
        };
       
        Thread thread2=new Thread(new Runnable() {
               
                @Override
                public void run() {
                       
                        while (true) {
                                System.err.println("2"+Thread.currentThread().getId()+Thread.currentThread().getName());
                               
                        }
                         
                       
                }
        });
        thread.start();
        thread2.start();
        }
}
但是有一个缺点就是匿名内部类找不到类的对象名字。只是很方便使用这个对象,在这里我觉得只使用一次的话用匿名内部类比较好一点。

评分

参与人数 1技术分 +1 收起 理由
枫儿 + 1 赞一个!

查看全部评分

回复 使用道具 举报
  1. class Ticket implements Runnable//extends Thread
  2. {
  3.         private  int tick=100;
  4.         public void run()
  5.         {
  6.                 while(true)
  7.                 {
  8.                         if(tick>0)
  9.                         System.out.println(Thread.currentThread().getName()+"  "+"sale  "+tick--);
  10.                 }
  11.         }
  12. }
  13. class  TicketDemo
  14. {
  15.         public static void main(String[] args)
  16.         {
  17.                 Ticket t=new Ticket();

  18.                 Thread t1=new Thread(t);
  19.                 Thread t2=new Thread(t);
  20.                 Thread t3=new Thread(t);
  21.                 Thread t4=new Thread(t);
  22.                 t1.start();
  23.                 t2.start();
  24.                 t3.start();
  25.                 t4.start();

  26.                 //Ticket t1=new Ticket();
  27.                 //Ticket t2=new Ticket();
  28.                 //Ticket t3=new Ticket();
  29.                 //Ticket t4=new Ticket();

  30.                 //t1.start();
  31.                 //t1.start();
  32.                 ///t1.start();
  33.                 //t1.start();
  34.         }
  35. }
复制代码

1,定义类实现Runnable接口
2,覆盖Runnable接口中的run方法
3,通过Thread类建立线程对象
4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法
回复 使用道具 举报
本帖最后由 yuon11937 于 2014-4-4 12:50 编辑

第一种方法是创建一个Thread类的子类定义一个线程,覆盖Thread类的run方法,创建Thread子类的对象,调用start方法启动线程。这种方法已经不再推荐使用了。举个简单例子你就会明白了:
class TestThread extends Thread {
        public void run() {
                for(int i=0;i<20;i++) {
                        System.out.println("自定义线程" +  Thread.currentThread().getName() + i);
                }
        }
}

public class MyThread
{
        public static void main(String[] args) {
                System.out.println("主线程" + Thread.currentThread().getName());
                TestThread tt = new TestThread();
                tt.start();               
        }
}

第二种方式:实现Runnable接口,覆盖接口中的run方法,创建Thread类的对象,将实现Runnable接口的子类对象,作为参数传递给Thread类的对象,最后调用Thread的start方法启动线程。实例代码如下:
class TestRunnable implements Runnable {
        public void run() {
                for(int i=0;i<20;i++) {
                        System.out.println("自定义线程" +  Thread.currentThread().getName() + i);
                }
        }
}

public class MyThread
{
        public static void main(String[] args) {
                System.out.println("主线程" + Thread.currentThread().getName());
                TestRunnable tt = new TestRunnable ();
                Thread t1 = new Thread(tt);
                Thread t2 = new Thread(tt);
                t1.start();
                t2.start();
        }
}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马