进程和线程的区别:进程是指运行中的应用程序,每一个进程都有自己的独立的内存空间,一个应用程序可以同时启动多个进程,比如多次打开同一个应用软件,多个火狐浏览器同时打开
线程是指进程中的一个执行流程,一个进程可以有多个线程组成,一个进程中可以同时运行多个不同的线程,分别执行不同的任务,当进程中的多个线程同时运行时,这种运行方式叫做并发运行
进程和线程的最主要区别:每个进程都需要操作系统为其分配单独的内存空间,而同一个进程中的所有线程在同一个进程中的所有线程在同一块地址空间工作,这些线程共享同一块内存和系统资源,比如共享一个对象或者已经打开的一个文件。
线程一共分为五个状态:新建状态,就绪状态,阻塞状态,运行状态,死亡状态
新建状态:当new创建一个线程的时候,这时候线程处于新建状态,线程并没有运行
就绪状态:线程并不会自动运行,只有当调用start方法才会启动,start方法会创建线程运行的系统资源,并调度执行run方法,当start方法返回的时候,线程处于就绪状态。处于就绪状态的线程不会立即执行run方法,线程必须还要和其他线程争夺cpu时间,只有获得了cpu时间才可以运行线程,对多个处于就绪状态的线程是由Java运行时系统的线程调度程序(thread
scheduler)来调度的。
运行状态:当线程获取cpu时间,进入运行状态,执行run方法
阻塞状态:阻塞状态中,线程并没有真正的结束运行,而是把cpu时间让出来,这时候其他处于就绪状态的线程获得cpu时间进入运行状态
死亡状态;正常run方法运行结束进入死亡状态,出现异常未捕获终止了run方法导致run方法中途猝死
就绪状态,阻塞状态,运行状态之间可以互相转换
线程中的一些方法比较:
就绪状态,阻塞状态,运行状态之间可以互相转换
① sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
与第二条有关,sleep方法进入阻塞状态,会让出cpu时间,也许优先级比较低的线程会执行,yield方法会转入就绪状态,只要获得cpu时间就会执行线程,不退让
② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
一旦某个线程调用了join方法,其他线程就会等到调用join方法的线程执行完之后才会执行(进入阻塞状态)
每一个线程操作时当且仅当此线程操作完成之后其他线程才会执行,原子操作
多个线程同时对一个共享数据操作时,会产生未知的结果,对此java引入了同步机制,在代表原子操作的代码前加入synchronized标记,这样叫做同步代码块
每个java对象都有只有一个同步锁,每个java程序只允许一个线程拥有一个同步锁,不可能两个线程同时拥有同步锁,当同步锁被其他线程占用时,后来的线程会被放入锁池,进入阻塞状态,等待获得锁,当线程执行完之后,其他线程随机获得锁执行,只有执行完同步代码块中的代码,才会释放锁,锁住的是对象
1、sleep()不释放对象锁。
2、wait()释放对象锁,把该线程放到等待池中,等待其他线程唤醒
3、notify()不释放对象锁。执行该方法的线程唤醒在等待池中的一个线程,java虚拟机从等待池中随机选择一个线程,把他转到锁池
只有获得了对象锁线程才会执行,即使调用了yield方法
如有不对,欢迎指正!