目录
1.多线程简单了解使用
1.创建线程的两种方式
1、继承继承Thread类
public class MyThread extends Thread{...}
2、实现Runnable接口
public class MyThread implements Runnable{...}
2.start与run方法
1、t.start()方法来启动线程,真正实现了多线程运行。t.run()是方法调用 2、通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行 3、run()方法称为线程体,它包含了要执行的这个线程的内容,线程就进入了运行状态,开始运行run函数当中的代码。run方法运行结束,此线程终止。然后CPU再调度其它线程
2.线程的生命周期
新建状态(new)、就绪状态(runnable),运行状态(running),阻塞状态(blocked),死亡状态(dead)
1、新建状态
当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由Java虚拟机为其分配内存,并初始化其成员变量的值
2、就绪状态
当线程对象调用了start()方法之后,该线程处于就绪状态。Java虚拟机会为其创建方法调用栈和程序计数器,等待调度运行
3、运行状态
如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则该线程处于运行状态
4、阻塞状态
阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。 阻塞的情况分三种: 1、等待阻塞(wait->等待对列): 运行(running)的线程执行wait()方法,JVM会把该线程放入等待队列(waitting queue)中。 2、同步阻塞(lock->锁池): 运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。 3、其他阻塞(sleep/join): 运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态
5、死亡状态
线程会以下面三种方式结束,结束后就是死亡状态。 1、正常结束:run()或call()方法执行完成,线程正常结束。 2、异常结束:线程抛出一个未捕获的Exception或Error。 3、调用stop:直接调用该线程的stop()方法来结束该线程—该方法通常容易导致死锁,不推荐使用。
3.线程调度常用方法
1、线程等待(wait )
Object类中的方法,调用该方法的线程进入WATING状态,只有等待另外线程的通知或被中断才会返回,需要注意的是调用wait()方法后,会释放对象的锁。因此wait方法一般用在同步方法或同步代码块中
2、线程唤醒(notify )
Object类中的notify()方法,唤醒在此对象监视器上等待的单个线程,如果所有线程都在此对象上等待,则会选择唤醒其中一个线程,选择是任意的,并在对实现做出决定时发生,线程通过调用其中一个wait()方法,在对象的监视器上等待,直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程,被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争。类似的方法还有notifyAll(),唤醒再次监视器上等待的所有线程
3、线程睡眠(sleep )
sleep导致当前线程休眠,与wait方法不同的是sleep不会释放当前占有的锁,sleep(long)会导致线程进入TIMED-WATING状态,而wait()方法会导致当前线程进入WATING状态
4、线程礼让(yield)
yield会使当前线程让出CPU执行时间片,与其他线程一起重新竞争CPU时间片。一般情况下,优先级高的线程有更大的可能性成功竞争得到CPU时间片,但这又不是绝对的,有的操作系统对线程优先级并不敏感
5、等待其他线程终止(join)
join()方法,等待其他线程终止,在当前线程中调用一个线程的join()方法,则当前线程转为阻塞状态,直到另一个线程结束,当前线程再由阻塞状态变为就绪状态,等待cpu的时间片。
6、线程中断(interrupt )
中断一个线程,其本意是给这个线程一个通知信号,会影响这个线程内部的一个中断标识位。这个线程本身并不会因此而改变状态(如阻塞,终止等)。 1、调用interrupt()方法并不会中断一个正在运行的线程。也就是说处于Running状态的线程并不会因为被中断而被终止,仅仅改变了内部维护的中断标识位而已。 2、若调用sleep()而使线程处于TIMED-WATING状态,这时调用interrupt()方法,会抛出InterruptedException,从而使线程提前结束TIMED-WATING状态。 3、许多声明抛出InterruptedException的方法(如Thread.sleep(long mills)),抛出异常前,都会清除中断标识位,所以抛出异常后,调用isInterrupted()方法将会返回false。 4、中断状态是线程固有的一个标识位,可以通过此标识位安全的终止线程。比如,你想终止一个线程thread的时候,可以调用thread.interrupt()方法,在线程的run方法内部可以根据thread.isInterrupted()的值来优雅的终止线程
7、线程方法总结
1、sleep():强迫一个线程睡眠N毫秒。 2、isAlive():判断一个线程是否存活。 3、join():等待线程终止。 4、activeCount():程序中活跃的线程数。 5、enumerate():枚举程序中的线程。 6、currentThread():得到当前线程。 7、isDaemon():一个线程是否为守护线程。 8、setDaemon():设置一个线程为守护线程。(用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束) 9、setName():为线程设置一个名称。 10、wait():强迫一个线程等待。 11、notify():通知一个线程继续运行。 12、setPriority():设置一个线程的优先级。 13、getPriority():获得一个线程的优先级。