java多线程内存图

多线程的例子

例一:

public class Test {
    public static void main(String[] args) throws Exception {
        Thread x1=new Thread(){
            @Override
            public void run(){
                for (int i = 0; i < 100; i++) {
                    System.out.println("我是线程x1,输出:"+i);
                }
            }
        };
        x1.start();

        for (int i = 0; i < 100; i++) {
            System.out.println("---->我是主线程,输出"+i);
        }
    }
}
部分运行结果:
0
===>发现这个结果是交替运行的
 
例二:
public class Test {
    public static void main(String[] args) throws Exception {
        Thread x1=new Thread(){
            @Override
            public void run(){
                Person w1=new Person();
                w1.m2();
            }
        };
        Thread x2=new Thread(){
            @Override
            public void run(){
                Person w1=new Person();
                w1.m3();
            }
        };

        x1.start();
        x2.start();

        Person w1=new Person();
        w1.m1();
    }
public class Person {
    public int age;
    public String name;

    public void m1() {
        System.out.println("m1方法开始");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("m1方法结束");
    }
    public void m2() {
        System.out.println("m2方法开始");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("m2方法结束");
    }
    public void m3() {
        System.out.println("m3方法开始");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("m3方法结束");
    }

    public static void m4() {
        System.out.println("m4方法开始");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("m3方法结束");
    }
}
运行结果:
0
 

对应内存原理图:

1、主方法入栈,并创建两个对象x1,x2(Thread()也在方法区,这里没有画),x1 x2new出来的两个线程对象进入方法区
0
 
2、
0
start( )表示进入就绪状态,句柄就是变量
14个内核就是说同一个时间只能同时执行14个任务。
 
  • 也就是说我们例二中的三个线程x1,x2,main要执行的话,必须抢占CPU。
  • 右击运行程序,包括 .start( ) 进入就绪状态,都是将他们三个交给操作系统进入就绪队列,而不是立即执行的意思。
  • 他们什么时候执行完全取决于操作系统。

就绪队列调度:

  • 就绪队列里边都是一个个的线程任务,供操作系统选择。
  • CPU每次执行任务会从就绪队列中选择一个执行,执行一段时间后切换。这段时间有可能把任务执行完,如果没有执行完就保留状态,再切换到其他线程。
  • 不一定先进入就绪队列的就先执行,先开始执行也不一定是先执行完的。
 
3、创建两个线程栈,栈中有run方法,run方法内分别创建了Person w1对象,并在堆中开辟对象空间。
0
4、w1中调用了m2方法,m2拷贝入栈; 另一个w1调用了m3方法,m3拷贝入栈。
0
4.1、m2方法中还调用了m3,m3拷贝入栈。
0
5、接下来 Person w1=new Person(); w1.m1(); 主线程也创建了w1对象,并调用了他的m1方法
0
到现在 还是在并行阶段,没有并发,没有竞争资源
 

让多线程竞争一个资源 成为并发

public class Test {
    public static void main(String[] args) throws Exception {

        Person k1=new Person();

        Thread x1=new Thread(){
            @Override
            public void run(){
                Person w1=new Person();
                w1.m2();
                k1.age++;
            }
        };
        Thread x2=new Thread(){
            @Override
            public void run(){
                Person w1=new Person();
                w1.m3();
                k1.age++;
            }
        };

        x1.start();
        x2.start();

        Person w1=new Person();
        w1.m1();
        k1.age++;
        System.out.println(k1.age);
    }
}
Person k1=new Person(); 增加 k1 对象,并且让三个线程对k1的age进行++操作。
 
--->可以发现,每次运行后的结果都不同
0
0
 
 
====>这样就说明了,写到同一个线程内的代码执行顺序有先后,但在不同线程中的代码就不能确定谁先谁后执行了。可能一个线程中的代码执行了两行后又切到了另一个线程了。
posted @   风筝上的猫  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示