您的位置:首页 > 编程语言 > Java开发

第一阶段:Java初级 ------- 多线程

2011-05-12 10:27 246 查看
进程和线程

进程:运行中的程序。

线程:程序被分段运行的代码。程序有很多段代码会被执行,程序要运行多少段代码,就需要多少条线程。多线程也就算多段代码交替运行.每条线程上都有要运行的代码段。

CPU以非常小的时间间隔来交替运行多个程序。虽然打开了多个程序,但是当前工作只有一个,其余都是待机状态。所含运行代码越快的线程,越容易先比其他线程完成。

-----------------------------------------------------------------------------

Thread 进程类

Thread.currentThread().getName()

Thread.currentThread()类中的一个静态方法,返回一个线程对象,表示当前正在执行的代码所在的线程的信息。

getName()每一个线程对象都有的一个返回当先代码正在执行的线程对象的名称。

Thread.strat() 启动一个线程的方法

run() strat()会调用的函数,我们要放到线程上的代码都放在这个RUN里面。

Thread 里的run()是空函数,不执行任何代码的。所以我们要放到线程上的代码,就必须

自己创建一个继承Thread的子类,并且定义一个覆盖它的RUN,然后将我们要用的代码放进去。还要把RUN声明为PUB,因为要让能被包外的父类Thread.start()所见。

姑且先这样认为Thread吧

class Thread
{
....

static Thread currentThread()
{
return new Thead() ;
}

char[] getName()
{
一些代码 ;

return "线程命" ;
}

void run(){}

void strar()
{
创建线程的代码;

run() ; //在线程上运行将代码

代码结束后的一些代码;
}

Thread(){}

}

我们要使用线程这样就可以了

class classname extends Thread
{
.....

public void run()
{
我们要放到线程里执行的代码 ;
}

.......
}

然后在需要使用线程的地方:

new classname().strat() ;

就大功告成了。

------------------------------------------------------------------------

后台线程 联合线程

在启动一个线程对象前,调用setDeamon(true),这个线程就成了后台线程,如果不调用或是调用时传递false,那就是前台线程。

在JAVA程序里,只要还有前台线程在运行,那么进程就不会结束,当没有前台线程或只有后台线程程序就会解释。

join(ARGS) 将一个线程合并到另一个线程里面,如果没参数,使得2个线程合为一个线程。然后将当前的加进来的线程代码运行完毕,然后再运行原来的线程。可以给一个整数参数,

表示时间,单位毫秒。让当前的线程暂时加入现在的线程一段时间,然后又离开当前线程,

成为一个单独线程。

线程1
{
线程2.join(arg) ;
}

------------------------------------------------------------------------

Thread( Runnable )

Runnable是一个接口,所以创建一个类来实现它,成为它的子类。然后NEW一个实例,

传到Thread里面。

单独以这样的方式来创建一个线程,和一般继承Thread没什么差别。

但是当要用多个代码都一样的线程,去处理同一份资源的时候,用上面的就很爽了。

------------------------------------------------------------------------

同步线程

当多个线程执行的是同一段代码的时候,由于线程和线程的跳转运行的不确定性,

会导致这段代码在还没执行完的时候就又被从新执行,这样代码的运行就遭到破坏,不安全。

所以要让这段代码在某条线程上运行时,不跳转,而是单次运行完毕,然后再进行跳转的运

作,从而保证的代码的安全。

这就是线程同步。将要同步的代码放到一个同步语句块里,想这样:

synchronized(一个对象) { code }

一定要注意对象的一致性!!! 目前THIS 和 STRING我用来做对象还没出过问题,但是INT不行。

try{ Thread.sleep(毫秒数) ;}catch(Exception e){CODE}

使当前线程暂停 毫秒数 后,继续再执行。

------------------------------------------------------------------------

线程通信

线程直接是没有通信的,各自单独存在,都不知道对方,对任意一条线程,它们都觉得

只有它们自己一条线程。所以线程的执行是无序的,很杂乱的。当然我们需要线程有序的执行

的时候,就要使用线程通信的东西,来使线程之间,按照一定的组织执行。

WAIT(): 线程遇见它的时候,该线程立即进入等待池,就算是休眠了,后面的代码都不执行。

NOTIFY(): 叫醒等待池里最前面的一个线程,让它处于启动状态,但是不一定马上就会执行。

NOTIFYALL(): 叫醒等待池所以线程。

------------------------------------------------------------------------

线程生命

只要一条线程上的代码没执行完,那么该线程就不会消亡,要注意,进入等待池的线程

只是休眠但是不是消亡。所以只要控制好线程上的代码就能控制好线程的生命。

需要注意的是,如果有线程在休眠,而又没有唤醒它的代码时,那么线程就停止不前

了,就像进入了死循环一样。

------------------------------------------------------------------------

下面举个列子吧

class main
{
public static void main( String[] args )  throws xcException
{

new  tz().passer();   //  启动通知黑马群出现通告者的线程

//上面的线程结束后,可能会出现异就是最后的输出语句不是最后输出。所以加一条延迟,但是不保证绝对有效
try{ Thread.sleep(100) ;}catch(Exception e){}

System.out.println( "/n不哈依稀··莫得名额求··等下一期吧····刚把的··^.^/n" ) ;

}
}

class tz
{
hmqs hm2 = new hmqs(70) ;  // 创建某一期的黑马,说明人数

public void passer()  //Thread 的构造函数,可以查阅相关文档。
{
new Thread(hm2,"①").start() ;
new Thread(hm2,"②").start() ;
new Thread(hm2,"③").start() ;
new Thread(hm2,"④").start() ;
}
}

class hmqs implements Runnable
{
private int pass ,idx ;  //  本期招收人数

hmqs( int pass ){ this.pass = pass ; }   //设置人数

public void run()
{
while( pass  > 0  )  //还有名额,就会有线程
{
synchronized(this)
{
if( pass > 0 ) //还有名额,就会产生通过者
{
System.out.println("/n你妹!黑马群 " + Thread.currentThread().getName()+
"  出现了第 "  +( ++idx )+" 个考试通过的!"+
"剩下名额只有 "+(--pass)+" 了。妹啊!!!") ;

notify() ;

if( pass >0 ) try{wait();}catch(Exception e){}   //  最后一个线程通知完后直接结束,就不睡觉了
//  不然,程序会停止不前的。
}

}
}
}
}

class xcException extends Exception{}  // 由于MAIN里的情况  必须抛出异常,该异常只能在输出里看到了。


------------------------------------------------------------------------

其实线程的学习不难,但是必须要动手,多犯错误,就能很好的理解了。大概也就是这样学习。

先了解线程的概念,然后要知道线程的不确定跳转和不确定顺序会带来的线程安全问题。然后

要解决 “不确定跳转”就要使线程代码同步,要解决 “不确定顺序”就要使用线程通信。

最后在联系根据具体情况控制线程的生命周期。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: