Thread与Runnable两种多线程方式

  • 多线程是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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值