Java- 简单了解线程 线程创建和联合线程(一)

       简单的了解一下JAVA的多线程后,觉的C#好像做的更好,C#通过委托的方式来实现多线程,当然JAVA实现多线程也很方便,但还是觉的C#做的更好。那么什么是多线程?一个进程中又可以包含一个或多个线程,一个线程就是一个程序内部的一条执行线索,如果要一程序中实现多段代码同时交替运行,就需要产生多个线程。

  线程的生命周期

  新建→运行→中断→死亡

  中断有: 1.当前线程切换到另一个线程时发生

       2.执行sleep时

       3.执行wait方法时,调用wait方法使线程进入等待后,如果想让他开启必须调用notify方法

 

  看一下单线程的情况,发现运行的结果他在线程MAIN里

public class test9 
{ 
    public static void main(String[] args)
    {
        new TestThread().run();
    }    
}

class TestThread
{
    public void run()
    {
        while(true)
        {
            System.out.println(Thread.currentThread().getName());
        }
    }
}

 

  用Thread类创建多线程

  我们要实现多线程,必须编写一个继承了Thread类的子类,子类要覆盖Thread类中的run函数,在子类的run函数中编写想在新线程上运行的程序代码。启动一个新的线程,我们不是直接调用Thread的子类对象的run方法,而是调用Thread子类对象的start方法;Thread类对象的start方法将产生一个新的线程,并在该线程上运行该Thread类对象中的run方法,根据面向对象的运行时的多态性,在该线程上实际运行的是Thread子类对象的run方法。

public class test9 
{ 
    public static void main(String[] args)
    {
        new TestThread().start();
        while(true)
        {
            System.out.println(Thread.currentThread().getName());
        }
    }    
}

class TestThread extends Thread
{
    public void run()
    {
        while(true)
        {
            System.out.println(Thread.currentThread().getName());
        }
    }
}

   由于我们没有给线程设置一个名字,所以使用语句 Thread.currentThread().getName() 他最后出来的是Thread-0

   那么把上面的程序改写一下,能过setName来给创建的线程取一个名字:我的第一个线程

View Code
public class test9 
{ 
    public static void main(String[] args)
    {
        TestThread t1 = new TestThread("我的第一个线程");
        t1.start();
        while(true)
        {
            System.out.println(Thread.currentThread().getName());
        }
    }    
}

class TestThread extends Thread
{
    TestThread(String name)
    {
        setName(name);
    }
    public void run()
    {
        while(true)
        {
            System.out.println(Thread.currentThread().getName());
        }
    }
}

 

  使用Runnable接口创建多线程

  Thread构造方法中有 Thread(Runnable target),Runnable他是一个接口类,该接口只有一个run方法。那么继承这个接口并实现他,就能实现多线程。使用Runnable接口来创建多线程比继承Thread类来创建多线程要更灵活,更好!但是只使用Runnable,就不能用setName方法。

public class test9 
{ 
    public static void main(String[] args)
    {
        Thread t1 = new Thread(new TestThread());
        t1.start();
        while(true)
        {
            System.out.println(Thread.currentThread().getName());
        }
    }    
}

class TestThread implements Runnable
{

    public void run()
    {
        while(true)
        {
            System.out.println(Thread.currentThread().getName());
        }
    }
}

 

  两种多线程方式的对比

  通过一个售票例子来对比两种线程,我们希望100张票在四个售票点卖。先试着用继承Thread来实现创建多线程方式试试。

View Code
public class test9 
{ 
    public static void main(String[] args)
    {
        TestThread t1 = new TestThread();
        t1.start();
        TestThread t2 = new TestThread();
        t2.start();
        TestThread t3 = new TestThread();
        t3.start();
        TestThread t4 = new TestThread();
        t4.start();        
    }    
}

class TestThread extends Thread
{
    int tickets = 100;
    public void run()
    {
        while(true)
        {
            if(tickets>0)
                System.out.println(Thread.currentThread().getName() + "还有多少张:"+ tickets--);
        }
    }
}

 

  运行的结果并不是我们想像的那样,发现他是四个售票点各卖100张票,我们希望的是100张票共用在四个售票点卖。那么应该怎么实现,显然用第一种多线程的方式难以实现,那么我们用第二种创建多线程的方式来实现。为了能清楚的看执行顺序,加一下Thread.sleep. 让线程小睡一会!

 

public class test9 
{ 
    public static void main(String[] args)
    {
        TestThread t = new TestThread();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
    }    
}

class TestThread implements Runnable
{
    int tickets = 100;
    public void run()
    {
        while(true)
        {
            try{Thread.sleep(10);}catch(Exception e){}
            if(tickets>0)
                System.out.println(Thread.currentThread().getName() + "还有多少张:"+ tickets--);
        }
    }
}

 

 

  

  使用setDaemon设置为后台线程(当一个程序为前台线程时,就算运行到main结束了,程序也要等前台线程结束了他才结束。但设置为后台线程,则是main函数结束了,那么程序就结束了。)上面的售票例子,发现运行到最后main函数程序并没有结束,对于JAVA程序来说,只要还有一个前台线程在运行,那么程序就不会结束。如果想让上面的程序要卖完售票后就结束,可以设置他为后台线程。

View Code
Class ThreadDemo1
{
    Public static void main(String[] args)
    {
        Thread tt = new TestThread();    
        tt.setDaemon(true);    
        tt.start();
}
}

Class TestThread extends Thread
{
    Public void run()
    {
        Whlile(true)
        {
            System.out.println(“run”+ Thread.currentThread().getName());
        }
    }
}

   

  联合 线程JOIN

  什么是联合线程?当前线程邀请调用方法的线程优先执行,在调用方法的线程执行结束之前,当前线程不能再次执行。运行下面程序看到一开始Thread和Main两个线程一开始交替运行,后来只有Thread一个在运行。产生这样的原因是因为调用了JOIN。(使得Thread和MAIN合并成一个线程,并且Thread线程排在MAIN线程的前面,所以Thread线程没有结束前就不会执行到MAIN线程)

public class test9 
{ 
    public static void main(String[] args)
    {
        Thread t = new Thread(new TestThread());
        t.start();
        int i=0;
        while(true)
        {
            if(i==100)
            {
                try{ t.join();}
                catch(Exception e){}
            }
            
            try{ Thread.sleep(10);}
            catch(Exception e){}
            System.out.println(Thread.currentThread().getName() + i++);
        }
    }    
}

class TestThread implements Runnable
{
    public void run()
    {
        int i = 0;
        while(true)
        {
                try{ Thread.sleep(10);}
                catch(Exception e){}
                System.out.println(Thread.currentThread().getName() + i++);
        }
    }
}

 

   看一下运行的结束:

  

  参考资料来源于:《JAVA就业培训教程》、《JAVA大学实用教程》

posted @ 2012-09-08 20:15  春天又来了  阅读(866)  评论(0编辑  收藏  举报