Java多线程理解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程理解相关的知识,希望对你有一定的参考价值。
首先说一下进程和线程的区别
进程:是计算机运用程序实例,拥有独立的内存空间和数据(猜测内存堆应该是作用的进程上),一个进程包含多个子线程,不同进程相互独立;
线程:cpu执行的基本单位,拥有独立的寄存器和栈,同一进程下的线程共享地址&内存空间;线程栈存放方法的栈帧,每次方法执行都会新建栈帧压到栈顶,当线程中某个请求大小超过限制则提示StackOverflowError,当需要存储一个新的栈帧且栈内存不足则抛出OutOfMemoryError;栈帧包含局部变量、返回值、方法引用的常量池(栈帧只能存储对象的引用)
cpu可以按时间切片执行,单核cpu同一个时刻只支持一个线程执行任务,多线程并发事实上就是多个线程排队申请调用cpu,cpu处理任务速度非常快,所以看上去多个线程任务说并发处理。
线程各个状态
1、新建状态(New):新创建了一个线程对象
2、就绪状态(Runnable):创建完线程并调用start()方法后等待获取cpu使用权,获取线程丢失cpu使用权后等待下一个cpu使用权
3、运行状态(Running):处于就绪状态的线程获取到cpu的使用权,执行程序代码
4、堵塞状态(Blocked):当某线程暂时放弃cpu使用权,该线程就处于堵塞状态,且处于堵塞状态线程不再申请调度cpu
a、等待堵塞:当对象调用wait方法,当前线程进入等待池,直到等待时间到或者调用该对象的notify方法
b、同步堵塞:当线程访问带同步锁的成员,且此时该同步锁被其它线程占用,该线程进入锁池,直到其它线程释放同步锁且当前线程获取到该同步锁
初
c、其它堵塞:调用当前线程sleep方法或者调用其它线程对象的join方法,直到sleep时间到期或者其它线程任务执行完
5、死亡状态(Dead):线程任务执行完毕或者线程抛出异常
如上状态流程图大体如下
虽然sleep和wait都能使线程进入等待状态,但两个方法差别如下:
1、sleep属于Thread类对象方法,wait属于Object类对象方法
2、调用线程对象sleep方法使得该线程处于等待状态,在时间到期之前不会申请调度cpu,如果该线程持有对象锁,则该线程不会释放对象锁;调用对象wait方法,持有该对象的线程进入等待池,且该线程会放弃对象锁
3、wait,notify等必须结合Synchronized来使用,sleep不需要
写了一个同步锁例子,三个子线程依次打印
public static void main(String[] args) { // TODO Auto-generated method stub Thread thread1=new ChildThread("thread1"); Thread thread2=new ChildThread("thread2"); Thread thread3=new ChildThread("thread3"); thread1.start(); thread2.start(); thread3.start(); } public class ChildThread extends Thread{ private static List<ChildThread> dataSource=new ArrayList<>(); private static Object lockObj=new Object(); private static int MaxLength=5; private int currentNumber=1; private String name; public ChildThread(String name) { this.name=name; dataSource.add(this); } @Override public void run() { super.run(); while (currentNumber<=MaxLength) { synchronized (lockObj) { boolean isbellow = isBellow(); if(isbellow){ Log.i(" " ,String.format("%s=%s",name,currentNumber)); currentNumber++; lockObj.notifyAll(); } else{ try { lockObj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } private boolean isBellow(){ boolean isBellow=true; for (ChildThread childThread:dataSource) { if(currentNumber>childThread.currentNumber){ isBellow=false; break; } } return isBellow; } }
结果如下
06-01 23:10:28.153 19108-19148/haozuo.com.myapplication I/: thread3=1
06-01 23:10:28.156 19108-19147/haozuo.com.myapplication I/: thread2=1
06-01 23:10:28.157 19108-19146/haozuo.com.myapplication I/: thread1=1
06-01 23:10:28.157 19108-19146/haozuo.com.myapplication I/: thread1=2
06-01 23:10:28.159 19108-19148/haozuo.com.myapplication I/: thread3=2
06-01 23:10:28.161 19108-19147/haozuo.com.myapplication I/: thread2=2
06-01 23:10:28.161 19108-19147/haozuo.com.myapplication I/: thread2=3
06-01 23:10:28.163 19108-19148/haozuo.com.myapplication I/: thread3=3
06-01 23:10:28.163 19108-19146/haozuo.com.myapplication I/: thread1=3
06-01 23:10:28.163 19108-19146/haozuo.com.myapplication I/: thread1=4
06-01 23:10:28.163 19108-19148/haozuo.com.myapplication I/: thread3=4
06-01 23:10:28.164 19108-19147/haozuo.com.myapplication I/: thread2=4
06-01 23:10:28.164 19108-19147/haozuo.com.myapplication I/: thread2=5
06-01 23:10:28.165 19108-19148/haozuo.com.myapplication I/: thread3=5
06-01 23:10:28.167 19108-19146/haozuo.com.myapplication I/: thread1=5
以上是关于Java多线程理解的主要内容,如果未能解决你的问题,请参考以下文章