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多线程理解的主要内容,如果未能解决你的问题,请参考以下文章

深入理解Java之多线程

java多线程

Java多线程-Java多线程概述

Java多线程1:进程与线程概述

[Java]多线程

[Java]多线程