黑马程序员-学习日记(多线程的初步认识)

 ------Java EE培训、Android培训、iOS培训、期待与您交流! -------


进程:正在执行的应用程序。一个应用程序运行时内存分配的空间。

线程:进程中一个程序执行的控制单元,一条执行路径。负责程序的执行顺序。
多线程:在java虚拟机启动的时候会有一个java.exe的执行程序,即一个进程。该进程中至少有一个线程负责java程序的运行。而且这个线程运行的代码存在于main方法中。
class Demo extends Thread 
{
    public void run() 
    {
        for (int i=0;i<60 ;i++ )
        {
            System.out.println("demo--"+i);
        }
    }
}
 class ThreadTest 
{
    public static void main(String[] args) 
    {
        Demo d = new Demo();
        Thread t =new Thread(d);
        d.start();
        for (int i=0;i<60 ;i++ )
        {
            System.out.println("main-------"+i);
        }

    }
}

运行后发现每一次结果都不同,因为多个线程都获取cpu的执行权。cpu执行到谁,谁就运行。至于执行多久,cpu说的算。
这就是多线程的特性之一:cpu每次只执行一个程序,只是在快速的不同线程间切换,表现了多线程的随机性
又如:
 class ThreadTest 
{
    public static void main(String[] args) 
    {
        Demo d1 = new Demo("one");
        Demo d2 = new Demo("two");
        
        //d1.start();
        //d2.start();
        d1.run();
        d2.run();
    }
}

使用run方法,d2必须等到d1执行完才会执行自己的代码(等于没有运行线程)。而使用start,相当于同时开启了两个独立的控制单元,已达到同时运行的目的,提高了效率。


示例: 模拟火车站四个售票窗口同时开通售票、票数20张、预计全部售完的情况。
第一种创建线程的方式
class Mlpc extends Thread //第一步、定义类继承Thread类
{
    private int ticket = 20; public void run() //第二步、覆写run方法,把需要被现场运行的代码都写在其中  { while(true) { if(ticket>0) { System.out.println(Thread.currentThread()+" "+ticket--); } } } } class mlpcDemo { public static void main(String[] args) { Mlpc m1 = new Mlpc();//第三步、通过创建Thread类的子类对象,创建了线程对象。 Mlpc m2 = new Mlpc(); Mlpc m3 = new Mlpc(); Mlpc m4 = new Mlpc(); m1.start();//第四步、调用start方法,开启线程,执行run方法  m1.start(); m1.start(); m1.start(); } }

很明显,结果会出现四条线程‘各自为营’,各卖20张票的情况。

以上结果肯定不符合要求,于是我们使用第二种创建线程的方式。

class Mlpc implements Runnable//第一步、定义类实现Runnable接口
{
    private int ticket = 20; public void run() //第二步、覆盖接口run方法,封装线程要运行的代码  { while(true) { if(ticket>0) { System.out.println(Thread.currentThread()+" "+ticket--); } } } } class mlpcDemo { public static void main(String[] args) { Mlpc m = new Mlpc(); Thread th0 = new Thread(m); Thread th1 = new Thread(m); Thread th2 = new Thread(m); Thread th3 = new Thread(m); th0.start(); th1.start(); th2.start(); th3.start(); } }

 

 

这样就对了。

run方法和 start方法

run方法 仅仅是对象调用方法,并没有运行线程 start方法 是开启线程并且执行线程中的run方法。

要有Runnable介面的出

1过继承Thread类的方式,可以完成多线程的建立。但是这种方式有一个局限性,如果一个类已经有了自己的父类,就不可以继承Thread类,因为java单继承的局限性。

可是该类中的还有部分代码需要被多个线程同时执行。这时怎么办呢?

只有对该类进行额外的功能扩展,java就提供了一个介面Runnable。这个介面中定义了run方法,其实run方法的定义就是为了存储多线程要运行的代码。

所以,通常创建线程都用第二种方式。

为实现Runnable介面可以避免单继承的局限性。


2实是将不同类中需要被多线程执行的代码进行抽取。将多线程要运行的代码的位置单独定义到介面中。为其他类进行功能扩展提供了前提。

所以Thread类在描述线程时,内部定义的run方法,也来自于Runnable介面。

 

实现Runnable介面可以避免单继承的局限性。而且,继承Thread,是可以对Thread类中的方法,进行子类复写的。但是不需要做这个复写动作的话,只为定义线程代码存放位置,实现Runnable介面更方便一些。所以Runnable介面将线程要行的任成了

 

class ThreadTest 
{
    public static void main(String[] args) 
    {
        ticket t = new ticket();
        Thread t0 = new Thread(t);
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        Thread t3 = new Thread(t);
        t0.start();
        t1.start();
        t2.start();
        t3.start();
    }
}

class ticket implements Runnable
{
    private int ticket = 100;

    public void run()
    {
        while(true)
            if(ticket>=0)
                System.out.println(ticket--);
    }
}

 

 

 

转载于:https://www.cnblogs.com/tozr/p/4148811.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值