黑马程序员技术交流社区

标题: 多线程 [打印本页]

作者: 周亮    时间: 2012-12-22 22:48
标题: 多线程
最近看多线程看的头昏脑胀的,把这两天学到的东西总结一下,加深下印象,同时也欢迎大家补充资料,共同探讨。
/*
多线程:

1,什么是线程?
        进程中的一个控制单元。进程中可以有多个控制单元。
2,开启多线程有什么好处呢?
        提高程序的运行效率。

演示示例:单线程程序。循环过大,停滞不前。
class Demo
{
        private String name;
        Demo(String name)
        {
                this.name = name;
        }
        public void function()
        {
                for(int x=0; x<10; x++)
                {
                        for(int y=-9999999; y<9999999; y++){}
                        System.out.println("name="+name);
                }
        }
}



创建线程:(真正在内存中创建控制单元,只有建立Thread对象,或者其子类对象才可以。)
首先,按照面向对象思想。思考java中是否已给我们提供这样的对象。
Thread类:用于描述线程的对象。

直接new其对象就可以在内存创建控制单元。

但是通过start方法开启的时候,它回去调用run方法。
多线程的出现就是了让其运行自定义的代码,提高这部分代码的运行效率。


因为start开启线程后会调用run方法,所以可以通过继承Thread类,并复写run方法。
将线程要运行的代码存放其中。

直接创建Thread类的子类对象,也可以在内存中建立控制单元。

代码演示:
class Demo extends Thread
{
        private String name;
        Demo(String name)
        {
                this.name = name;
        }
        public void run()
        {
                for(int x=0; x<10; x++)
                {
                        for(int y=-9999999; y<9999999; y++){}
                        System.out.println("name="+name);
                }
        }
}

main()
{
        Demo d1 = new Demo("one");
        Demo d2 = new Demo("two");
        d1.start();
        d2.start();
}

发现结果有些不一样。onetwo一起输出。说明多线的开启可以提高运行,two不在等待one。
每一次的运行结果都有可能不一样。那么因为线程的随机性。

因为多个线程在“互抢”cpu资源。

曾经写的程序都是单线程的,这个线程叫做主线程,线程名称是:main
线程的方法的使用:
static Thread currentThread():获取当前执行的线程对象。
String getName():获取线程名称。Thread_0.....

线程的四种状态:

1,被创建。
2,运行。
3,冻结。
4,消亡。

售票的例子。

需求:
想要通过四个窗口将100张票随机售出。

class SaleTickets extends Thread
{
        private int ticks = 100;
        public void run()
        {
                while(true)
                {
                        if(ticks>0)
                        {
                                System.out.println(currentThread().getName()+"---sale : "+ticks--);
                        }
                }
        }
}
main()
{
        SaleTickets s1 = new SaleTickets();
        s1.start();
        s1.start();
}

创建线程的第二种方式:实现Runnable接口。
class SaleTickets implements Runnable
{
        private int ticks = 100;
        public void run()
        {
                while(true)
                {
                        if(ticks>0)
                        {
                                System.out.println(currentThread().getName()+"---sale : "+ticks--);
                        }
                }
        }
}
main()
{
        SaleTickets s = new SaleTickets();
        Thread t1 = new Thread(s);
        Thread t2 = new Thread(s);
        Thread t3 = new Thread(s);
        Thread t4 = new Thread(s);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
}


第二种方式有什么好处呢?

1,避免了单继承的局限性。
2,可以让线程去共享资源。

扩展部分:

Runnable是如何由来的?

多线程要运行的代码存放在不同的描述当中,就将这些代码的位置进行向上抽取。
定义一个接口,用于扩展的。规则定义的线程运行的代码存放的位置。

当一个类有了自己的父类时,就不可以在继承Thread了,可以该类中还有需要不被多线程所执行的代码。
这些这个类可以实现Runnable接口。

但是这个类对象和线程没有关系,那么就将该类对象作为参数传递给Thread类构造函数。
让Thread类对象去运行指定对象的run方法;


模拟线程的体系建立。

interface MyRunnable
{
        public void run();
}

class MyThread implements MyRunnable
{
        private MyRunnable r;
        MyThread(){}
        MyThread(MyRunnable r)
        {
                this.r = r;
        }
        public void run()
        {
                if(r!=null)
                        r.run();
        }
        public void start()
        {
                run();
        }
}
*/


class  DemoMain
{
        public static void main(String[] args)
        {
                Demo d1 = new Demo("one");
                Demo d2 = new Demo("two");
                d1.function();
                d2.function();
        }
}



作者: 许庭洲    时间: 2012-12-23 07:51
值得学习ing!
作者: 焦健    时间: 2012-12-24 01:48
Runnable由来的部分有几个错字,意思就不一样就,改下吧,,当一个类有了自己的父类时后面这两句!
还有模拟线程这里看得不是很明白,接口中的方法没有方法体,在run方法中调用有意义吗?抓机党,不方便验证啊。
作者: 陈进    时间: 2012-12-24 18:41
值得学习啊。。。。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2