Java多线程
多线程可以理解成多个任务,每个任务可以理解成一个线程,而能执行多个线程的程序称为多线程程序。
线程也被称为轻量级进程,是程序执行流的最小单元,一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成;
进程是系统进行资源分配和调度的基本单位,可以将进程理解为一个正在执行的程序;
线程是程序执行的最小单位,一个进程可以由一个或多个线程组成;
线程是进程中的一个实体,是被系统独立调度和分派的基本单位;
一个线程可以创建和撤消另一个线程,同一个进程中的多个线程之间可以并发执行。
由于线程之间的相互制约,致使线程在运行中呈现出间断性;每个程序至少有一个线程,若程序只有一个线程,那就是程序本身;
多线程的特点:
提高应用程序的响应,提高计算机的CPU的利用率;
改善程序结构;
线程状态:
线程包括5种状态:新建状态(New)、就绪状态(Runnable)、运行状态(Running)、堵塞状态(Blocked)、死亡状态(Dead);
wait()、notify()、nofityAll()方法:
wait():让当前线程进入等待状态/阻塞状态,同时,wait()也会让当前线程释放它所持有的锁;
notify()和notifyAll():唤醒当前对象上的等待线程,使其进入“就绪状态”;notify()是唤醒单个线程,notifyAll()是唤醒所有线程;
yieId()、sleep()、join()和interrupt()方法
yieId():yieId方法不会释放锁;
yieId是Tread类的静态方法;能让线程从“运行状态”进入到“就绪状态”,从而让其他具有相同优先级的等待线程获取执行权;但是具有同样优先级的线程不一定能获得执行权,也有可能当前线程又进入到“运行状态”继续执行;
sleep():sleep()方法也不会释放锁;
sleep()是Thread类的静态方法;
sleep()让当前线程从“运行状态”进入到“阻塞状态”,sleep有两个重载方法:
static void sleep(long millis); static void sleep(long millis,int nanos):
join():join()是Thread的一个实例方法。当程序执行流中调用其他线程的join方法时,调用的线程将进入阻塞状态,直到被join的线程执行完;
join的3种重载:
join() : 等待被join的线程执行完成
join(long millis) : 等待被join的线程的时间最长为millis毫秒,若在millis毫秒内,被join的线程还未执行结束,则不等待。
join(long millis , int nanos) : 等待被join的线程的时间最长为millis毫秒加nanos微秒,若在此时间内,被join的线程还未执行结束,则不等待。
interrupt():用于中断当前线程;
interrupt()方法不会中断一个正在运行的线程,它用于提前退出线程的阻塞状态,也就是说当线程通过Object.wait() / Thread.sleep() / Thread.join() / 方法进入阻塞状态后,如果调用线程中断方法,该线程会收到一个InterruptedException中断异常,可以在catch中编写自己需要的代码。
interrupt()是Thread类的一个实例方法。当interrupt()被调用时,会立即将线程的中断标志设置为“true”。当要中断处于“阻塞状态”的线程时,由于线程正处于阻塞状态,因此中断标记会被设置为“false”,抛出一个 InterruptedException异常。我们在线程的循环外捕获这个异常,就可以退出线程了。
interrupt()并不会中断处于“运行状态”的线程,它会把线程的“中断标记”设置为true,所以我们可以不断通过isInterrupted()来检测中断标记,从而在调用了interrupt()后终止线程,这也是通常我们对interrupt()的用法。
Interrupted()是Thread类的一个静态方法,它返回一个布尔类型指明当前线程是否已经被中断,isInterrupted()是Thread类的实例方法,返回一个布尔类型来判断线程是否已经被中断。它们都能够用于检测对象的“中断标记”。区别是,interrupted()除了返回中断标记之外,还会清除中断标记(即将中断标记设为false);而isInterrupted()仅仅返回中断标记。
Synchronized关键字
使用synchronized修饰的方法是同步方法,多个线程调用同一个对象的同步方法时会顺序同步执行。在java中,每一个对象有且仅有一个同步锁。这也意味着,同步锁是依赖于对象而存在。 当前线程调用某个对象的synchronized方法时,就获取了该对象的同步锁。例如,synchronized(obj),当前线程就获取了“obj这个对象”的同步锁。
不同线程对同步锁的访问是互斥的。