//操作系统可以产生多个进程,每个进程也可以产生多个线程

1.线程

//"主线程”是main线程

//线程有4种状态:新建、运行、中断、死亡

(1)新建:

①通过继承Thread类创建:

需要重写Thread类的run()方法;

//优点:可以在子类中增加新的成员变量和方法,使线程具有某种属性和功能。

  缺点:Java不支持多继承,Thread类的子类不能再扩展其他的类。

 

②通过实现Runnable接口创建:

构造方法:Thread(Runnable target)

//优点:对于使用同一目标对象的线程,目标对象的成员变量是这些线程共享的数据单元;

     创建目标对象的类在必要时可以是某个特定类的子类。

因此使用Runnable接口比使用Thread的子类更具有灵活性。

 

 

中断原因:

①JVM将CPU资源从当前线程切换给其他线程,使本线程让出CPU的使用权处于中断状态。

②线程使用CPU资源期间,执行了sleep(int millsecond)方法,使当前线程进入休眠状态。

③线程使用CPU资源期间,执行了wait()方法,使得当前线程进入等待状态。

④线程使用CPU资源期间,执行某个操作进入阻塞状态,比如执行读/写操作引起阻塞。

 

死亡(线程释放了实体和线程对象的内存)原因:

①执行完run()方法中的全部语句,结束了run()方法。

②线程被提前强制性地终止,即强制run()方法结束。

 

目标对象与线程的关系:

①完全解耦:目标对象没有组合线程对象。

②弱耦合:目标对象可以组合线程,即将线程作为自己的成员(在Thread子类或实现Runnable的类中创建线程)。

//在实际问题中,根据实际情况确定目标对象和线程是组合或完全解耦关系,两种关系各有优缺点。

 

线程的常用方法:

1.start() throws IllegalThreadStateException

启动线程,二次调用start()方法会导致异常;

2.run()

定义线程对象被调度之后所执行的操作,系统自动调用而用户程序不得引用;

3.sleep(int millsecond) throws InterruptedException

参数millsecond是以毫秒为单位的休眠时间,如果线程在休眠时被打断,JVM就抛出异常;

4.isAlive()

判断线程是否存在(非新建和死亡状态);

5.currentThread()

返回当前正在使用CPU资源的线程;

6.interrupt()

"吵醒"休眠的线程,导致休眠的线程发生InterruptedException异常;

7.setPriority(int grade) throws IllegalArgumenException

调整线程的优先级,参数grade参数为1~10之间,若不在该范围则发生异常(注意有些os只识别3个级别:1、5和10);

//实际编程中,不提倡使用线程的优先级来保证算法的正确执行

 

2.线程同步(用synchronized修饰)

线程同步机制:当一个线程A使用synchronized方法时,其他线程想使用这个synchronized方法时就必须等待,直到线程A使用完该synchronized方法。

同步方法中的方法(都是Object类的final方法):

1.wait()

中断线程的执行,使本线程等待,暂时让出CPU的使用权;

2.notify()

通知处于等待中的某一个线程结束等待;

3.notifyAll()

通知所有由于使用这个同步方法而处于等待的线程结束等待,曾中断的线程从刚才的中断处继续执行这个同步方法;

//不可以在非同步方法中使用上述的三个方法

//遵循"先中断先继续”的原则

 

3.线程联合

一个线程A在占有CPU资源期间,可以让其他线程调用join()方法和本线程联合,如:B.join();

如果线程A在占有CPU资源期间一旦联合B线程,那么A线程将立刻中断执行,一直等到它联合的B线程执行完毕,A线程再重新排队等待CPU资源,以便恢复执行。

//如果A准备联合的B线程已经结束,那么B.join()不会产生任何效果。

 

4.GUI线程

当Java程序包含GUI时,JVM在运行程序时会自动启动更多的线程,其中两个重要的线程:AWT-EventQuecue和AWT-Windows

当触发ActionEvent事件时,AWT-EventQuecue线程就立刻等候执行处理事件的代码。

 

5.计时器线程

javax.swing.Timer类(避免与java.util.Timer类混淆):

构造方法:

Timer(int a)

必须调用addActionListener(ActionListener listener)方法获得监视器(必须是组件类);

Timer(int a,Object b)

参数a的单位是毫秒,确定计时器每隔a毫秒"振铃"一次,参数b是计时器的监视器;

 

常用方法:

1.setReapeats(boolean b)

只想计时器振铃一次,可以调用此方法,参数b取值false;

2.setInitialDelay(int depay)

设置首次振铃的延时,默认延时为a;

3.start()

启动计时器;

4.stop()

停止计时器,即挂起线程;

5.restart()

重新启动计时器,即恢复线程;

 

6.守护线程

线程默认是非守护线程(用户线程),一个线程调用void setDaemon(boolean on)方法将自己设置成一个守护线程,如:thread.setDaemon(true);

当所有用户线程结束运行时, 即使守护线程的run方法还未执行完,也立刻结束运行。

//守护线程用来做一些不是很严格的工作

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!

相关课程