Thread与Runnable两种多线程方式

来源:互联网 发布:电脑版office2010软件 编辑:程序博客网 时间:2024/06/16 04:12
  • 多线程是Java一大特点,如果没有多个处理器,在逻辑上还是单核处理器在执行,如果在语言层面给予支持多核处理器可以在微观上同时的执行程序,Intel处理器支持超线程技术,例如双核四线程的i3甚至是8核16线程的i7处理器,还有面向服务器的xeon处理器,服务器注重的可靠性与稳定性因此并不会把单核的主频提升太高,但是对多线程的支持是解决高并发与资源共享的好方法。
  • 线程是进程的子集,也是操作系统调度的最小单位,一个或则多个线程完成一个进程。线程对应的JVM里的栈。启动一个线程总是先有栈,当生成对象的时候才会在堆上创建对象。
  • java里启动多线程有Thread与实现Runable接口的两种方法,参考网上的相关教程,这次写点入门的笔记。
  • 执行线程,可以用run和start两个方法,run并没有启动新线程,只是顺序的执行了run方法。start方法会启动新的线程,而且start方法可以调用操作系统的底层函数,达到交替执行的目的。
class MyThread extends Thread{    //创建一个Thread的子类    String name;    @Override    public void run()    {        for(int i = 0;i < 10;i ++)        {            System.out.println(name + " " + i);        }    }    MyThread(String name)    {        this.name = name;    }}

测试:

        /*         * run与start执行方式的区别         */        MyThread m1 = new MyThread("micro");        MyThread m2 = new MyThread("xiaoma");        m1.start();//启动新线程,可实现交替执行        m2.start();//一旦调用start方法,JVM会自动找到run方法去执行,可调用底层函数        m1.run();//如果直接执行run的方式,m1执行完再执行m2        m2.run();

参考jdk源码Thread本身就实现了Runnable接口,Thread里有一个Thread(Runnable target)方法,可以传入Runnable的实现类,然后去执行run或则start方法。

class MyThread2 implements Runnable{    String name;    MyThread2(String name)    {        this.name = name;    }    @Override    public void run() {        // TODO Auto-generated method stub        for(int i = 0;i < 10;i ++)        {            System.out.println(name + " " + i);        }    }}

测试:

        /*         * 在实际开发中,很少直接使用继承Thread的方式去启动多线程         * 而是使用实现Runnable接口         */        System.out.println("Thread启动Runnable实现类");        MyThread2 m3 = new MyThread2("micro2");        MyThread2 m4 = new MyThread2("xiaoma2");        new Thread(m3).start();        new Thread(m4).start();
  • 比较这两种方法,一般使用Runnable接口传入Thread的方法要多些,这样克服了单继承的局限性还可以达到共享变量的效果,关于共享变量,参考一个卖票的教程,例子有点小问题,但是在回帖中大家都指正了错误:
    如果用Thread启动线程实现卖票:
    System.out.println("卖票资源无法共享");        ThreadTicket m5 = new ThreadTicket();        ThreadTicket m6 = new ThreadTicket();        m5.start();//start有调用底层本地方法可以合理交替执行run方法        m6.start();//两个线程,每个线程售票10张
//此售票方法,每个卖出了10张票,无法达到资源共享的目的class ThreadTicket extends Thread{    private int ticket = 10;    @Override    public void run()    {        while(true)        {            if(ticket > 0)            {                System.out.println("此时剩余票:"+ticket);                ticket --;            }            else            {                break;            }        }        System.out.println("票数为"+ticket+" 售票结束");    }    }

通过实现Runnable接口的方法:

        /*         * 如果使用Runnable接口,就可以实现共享         */        ThreadTicket2 m7 = new ThreadTicket2();        new Thread(m7).start();        new Thread(m7).start();//虽然两个线程,但一共售出了10张票
//Runnable接口实现资源共享的目的class ThreadTicket2 implements Runnable{    private int ticket = 10;    @Override    //注意此处需要加锁控制同步,保证线程安全    public synchronized void run() {        // TODO Auto-generated method stub        while(true)        {            if(ticket > 0)            {                System.out.println("此时剩余票数:"+ticket);                ticket --;            }            else            {                break;            }        }        System.out.println("剩余票数为"+ticket+" 停止售票");    }}
0 0
原创粉丝点击