Java四线程2个好玩的题材

  标题代码如下,问题:程序的输出结果?

public class TestSync2 implements Runnable {
    int b = 100;          

    synchronized void m1() throws InterruptedException {
        b = 1000;
        Thread.sleep(500); //6
        System.out.println("b=" + b);
    }

    synchronized void m2() throws InterruptedException {
        Thread.sleep(250); //5
        b = 2000;
    }

    public static void main(String[] args) throws InterruptedException {
        TestSync2 tt = new TestSync2();
        Thread t = new Thread(tt);  //1
        t.start(); //2
        tt.m2(); //3
        System.out.println("main thread b=" + tt.b); //4
    }

    @Override
    public void run() {
        try {
            m1();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

  答案:

main thread b=2000
b=1000
或
main thread b=1000
b=1000

  分析:

  首先熟知下synchronized的用法:

  • 钦定加锁对象:对给定对象加锁,进入同步代码前须要活的加以对象的锁。
  • 直接效果于实例方法:相当于对脚下实例加锁,进入同步代码前要获取当前实例的锁。
  • 直白成效于静态方法:约等于对当前类加锁,进入同步代码前要取妥当前类的锁。

  恐怕存在的误区:

  ① 、由于对synchronized驾驭的不到位,由于不少时候,我们四线程都以操作1个synchronized的法子,当2个线程调用1个不等synchronized的办法的时候,认为是未曾关联的,那种想法是存在误区的。直接效果于实例方法:相当于对当下实例加锁,进入同步代码前要赢稳妥前实例的锁。

  ② 、假若二个调用synchronized方法。其余多个调用普通方法是未曾提到的,八个个是不存在等待关系的。

  分析流程:

  Java
都以从main方法执行的,上边说了有3个线程,不过此地正是修改线程优先级也没用,优先级是在2个程序都还从未实施的时候才有先后,今后那些代码一举行,主线程main已经推行了。对于属性别变化量
int b
=100出于选用了synchronized也不会存在可知性难点(也向来不供给再使用volatile证明),当执行1步骤的时候(Thread
t = new Thread(tt);
//1)线程是new状态,还未曾从头工作。当执行2步骤的时候(t.start();
//2)当调用start方法,那么些线程才正真被运营,进入runnable状态,runnable状态表示能够进行,一切准备稳当了,可是并不表示必定在cpu上边执行,有没有确实执行取决服务cpu的调度。在那边当执行3手续必定是先取得锁(由于start必要调用native方法,并且在用完毕之后在整体准备妥贴了,然而并不代表一定在cpu上面执行,有没有实在实施取决服务cpu的调度,之后才会调用run方法,执行m1方法)。那里实在3个synchronized方法里面包车型客车Thread.sheep其实要不要是冷淡的,估算是就为混淆扩展难度。3手续执行的时候实在不慢子线程也准备好了,可是由于synchronized的存在,并且是职能一样对象,所以子线程就只有必须等待了。由于main方法里面实践顺序是逐一执行的,所以必须是手续3实践到位今后才能够到4步骤,而由于3手续执行到位,子线程就足以推行m1了。这里就存在一个十二线程哪个人先得到到的题材,假设4手续先拿走那么main
thread
b=3000,如若子线程m1取得到大概就b已经赋值成一千要么还未曾来得及赋值4手续就输出了可能结果就是main
thread b=一千恐怕main thread
b=三千,在那边如若把6步骤去掉那么b=执行在前和main thread
b=在前就不鲜明了。然而出于6手续存在,所以不管怎么都以main thread
b=在前面,那么等于一千依然3000看事态,之后b=一千是任其自然固定的了。

相关文章