问答 [每日一题][java] 关于多线程

bauul · 2018年06月22日 · 最后由 bauul 回复于 2018年06月25日 · 2362 次阅读

java version

jdk8_151 64 位

代码

package com.clark;

public class MyRunnable implements Runnable {

    public void run() {
        System.out.println("hh!");
    }
}

package com.test;

import com.clark.MyRunnable;

public class Run {

    public static void main(String[] args) {
        Runnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();

        Thread t1 = new Thread(thread);
        t1.start();
        System.out.println("Over!");
    }

}

问题很简单,上面的代码有哪些可能的输出?为什么?

自答

其实这个是自己看书,随便想出来玩的,在执行过程中呢,发现有两个答案,
输出一:

Over!
hh!

输出二:

Over!
hh!
hh!

开始呢,我以为是 BUG 来的,后来发现,当线程 thread 先执行的时候就是输出一,当 t1 先执行的时候就是输出二,
如何证明呢?只要将线程 ID 输出就可以了

public class MyRunnable implements Runnable {

    public void run() {
        System.out.println("currentId:"+ Thread.currentThread().getId());
        System.out.println("hh!");
    }
}

public class Run {

    public static void main(String[] args) {
        Runnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        System.out.println("thread-0:" + thread.getState());
        thread.start();
        System.out.println("thread-id:" + thread.getId());
        System.out.println("thread-1:" + thread.getState());

        Thread t1 = new Thread(thread);

        System.out.println("t1-id:" + t1.getId());
        System.out.println("t1-state:" + t1.getState());
        System.out.println("thread-2:" + thread.getState());
        System.out.println("t1-0:" + thread.getState());
        t1.start();
        System.out.println("t1-state:" + t1.getState());
        System.out.println("t1-1:" + thread.getState());
        System.out.println("Over!");
    }

}

但是一想,这也还是很奇怪,即使两个线程执行顺序不同,也应该是输出二才对,怎么会有输出一的情况呢?
还是有些疑惑的

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 14 条回复 时间 点赞
  • 因为不太懂 java,所以无法作答
  • 最近坛子越来越冷,好像是大家都趋于理性了,或者是无所谓的态度,说白了是现在的社会态度
  • 发现越来越多的面试或者相关的人都喜欢讨线程进程携程,讲真,这个在工作中真的会用到么,除非你去撸开发代码, 或真是自己开发需要加锁等等;可能干上这类似工作人又有多少?欢迎来喷
hellohell 回复

现在的社区已经不是技术讨论了,各种吐槽抱怨,各种小白问题,测试人员也好,公司也好,大多都在追求各种看起来高大上的技术,真正拥抱业务的没多少,测试确实越来越靠近开发,但很多人忘记了测试的意义,一味地为了技术而学习开发,而不是为了更好地服务测试

hellohell 回复

简单点说等需要用了,才去学,已经迟了

4楼 已删除

出这种题目意义何在?
一共三个线程 thread 线程,t1 线程,主线程。

以下线程为什么是错误的,原因在哪里?这才是最最基本的线程题。

public class VolatileNoAtomic extends Thread{
    private static volatile int count = 0;
    private static void addCount(){
        for (int i = 0; i < 1000; i++) {
            count++ ; 
        }
        System.out.println(count);
    }

    public void run(){
        addCount();
    }

    public static void main(String[] args) {
        VolatileNoAtomic[] arr = new VolatileNoAtomic[100];
        for (int i = 0; i < 10; i++) {
            arr[i] = new VolatileNoAtomic(); 
        }
        for (int i = 0; i < 10; i++) {
            arr[i].start(); 
        }
    }
}
konami1986 回复

main 方法中第二个 for 循环会导致多个线程同时去跑 VolatileNoAtomic 类中 addCount 方法,假如第一个线程循环了 50 次第二个线程进来了将 i 变成 0 循环了几次后第一个线程循环第 51 次的时候又将 i 变成 0 进入了死循环,是这样吗?

昨天有雨 回复

volatile 关键字不具备原子性

konami1986 回复

三个线程,然后呢?

konami1986 回复

这个 2.3.4 的例子,你确定你真的理解了?

bauul 回复

不知道这题目意义在哪里?

 Runnable runnable = new MyRunnable();
  Thread thread = new Thread(runnable);
  thread.start();

//  Thread t1 = new Thread(thread);
  Thread t1 = new Thread(runnable );
  t1.start();
  System.out.println("Over!");
6楼 已删除
konami1986 回复

有点没看明白,可以说详细些吗?

13楼 已删除
bauul #14 · 2018年06月25日 Author

你的结果看起来比较正常,请问是哪个版本的 java?

匿名 · #15 · 2018年06月25日
仅楼主可见
bauul #16 · 2018年06月25日 Author

我的 java 版本:
"C:\Program Files\Java\jdk1.8.0_151\bin\java.exe"
版本是不一样,估计和机器硬件性能也有关了

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册