当前位置: 首页 > 面试题库 >

Java中的线程如何工作,以及它们的工作方式与方法中的基本代码有何不同?

夏谦
2023-03-14
问题内容

基本上,此代码在两个类中创建了两个线程,它们从第三类中调用。每个线程都有一个循环,每次循环后都会进入休眠状态。

(代码末尾)

输出为:

CHECK 0 CHECK
CHECK 1 CHECK
run one
in thread1 
CHECK 2 CHECK
run two
in thread2

1)我不知道为什么它会这样工作。我的意思是应该先打印“ CHECK 0 CHECK”。但是,为什么在线程1之前打印CHECK 1
CHECK(而在代码中调用Thread1之后才打印),而对于CHECK 2 CHECK和Thread2却一样?

2)如果我用System.exit(0)替换CHECK 2 CHECK,如上述情况,在运行Thread2之前进行了Thread2旁边的CHECK 2
CHECK的打印,为什么System.exit(0)在之后发生在这种情况下运行Thread2?

第二种情况的输出:

CHECK 0 CHECK
CHECK 1 CHECK
run one
in thread1 
run two
in thread2

请说明为什么会这样吗?为什么方法中的线程和代码会以这种方式混淆?我想我对Java如何管理线程一无所知。我尝试了很多搜索,但是找不到我能理解的任何东西。

码:

public class Thread1 implements Runnable 
{

    public Thread1()
    {
        new Thread(this).start();
    }

    public void run() 
    {
        // TODO Auto-generated method stub
        System.out.println("run one");
        try
        {
            for(int i = 0; i < 5;i++)
            {
                System.out.println("in thread1 ");
                Thread.sleep(1000);
            }
        }
        catch(Exception e)
        {
            //e.printStackTrace();
        }
    }

}

public class Thread2 implements Runnable 
{

    public Thread2()
    {
        new Thread(this).start();
    }

    public void run() 
    {
        // TODO Auto-generated method stub
        System.out.println("run two");
        try
        {
            for(int i=0;i<5;i++)
            {
                System.out.println("in thread2 ");
                Thread.sleep(1000);
            }
        }
        catch(Exception e)
        {
            //e.printStackTrace();
        }
    }
}

public class Threadjava
{
    public static void main(String[] str)
    {
        System.out.println("CHECK 0 CHECK");
        new Thread1();
        System.out.println("CHECK 1 CHECK");
        new Thread2();
        System.out.println("CHECK 2 CHECK");
        //The above is deleted in the second case
        System.exit(0);
        System.out.println("CHECK 3 CHECK");
    }
}

问题答案:

嗯,这是一个普遍的误解,因为Java程序本质上是单线程的,因为它们不是。当您启动Java程序时,它正在Java虚拟机中执行,该Java虚拟机将启动其他几个线程来执行您的代码。检查这个不错的博客:

http://blog.jamesdbloom.com/JVMInternals.html#jvm_system_threads

在您的情况下,最重要的是启动一个主线程,该线程执行一个main方法。从那里开始,您将计划执行两个单独的线程Thread1和Thread2,但是您不知道什么时候OS调度程序会选择它们真正执行。由于许多原因,它不是确定性的:

  • 您不知道使用什么算法调度程序来拾取要执行的线程,
  • 您不知道处理器有多少个内核,线程可能并行或串行运行
  • 即时编译器可能会重新排列和优化您的代码,
  • CPU可能会重新安排对IO的读写,以优化代码的执行,
  • 您的代码中可能存在导致数据争用,争用条件,饥饿等的错误。

Java并发性是一个很难的话题,而我发送给您的博客条目是一个很好的起点,值得一去。如需认真阅读,请访问http://www.amazon.com/Java-
Concurrency-Practice-Brian-
Goetz/dp/0321349601

祝好运。



 类似资料:
  • 问题内容: 我的多线程概念薄弱,正在尝试学习。 在Java中,我所知道的是,我们不能多次调用一个线程: 据我所知,当您再次调用该函数时,它会引发异常,因为一旦线程退出方法,并且您试图再次初始化事物,该线程的关联堆栈就会被破坏。 在那种情况下,我对线程池的了解是,它提供了更好的性能并节省了时间,因为不需要创建新线程(我在此阅读)。 如果不需要在线程池中创建新线程,那么它如何与刚刚完成其run方法的同

  • 问题内容: 我很好奇java如何通过使用Object API的hashCode()方法生成哈希值? 问题答案: Java不会生成hashCode(),即此处没有自动发生的情况。但是,根据对象实例的内存地址生成HashCode。大多数类(尤其是如果要在任何API中使用它的类)都应该实现自己的HashCode(并通过契约使用自己的equals方法)。

  • 你能区分process和Update吗?由于我刚接触JSF,所以我不太清楚该在哪里使用。不必要的使用会导致我的应用程序出现问题。

  • 何时扩展RecyclerView.Adapter以及它是如何工作的? 我理解一段代码有困难。有人能解释一下这个方法什么时候扩展,它是用来做什么的吗?

  • 问题内容: 我正在尝试Java线程方法的示例。但是我发现即使线程已经启动,该方法仍在返回。有人可以告诉我我在做什么错吗?这是代码片段。 问题答案: 如果我的记忆很好,那么java在线程切换之间会有很长的时间间隔,因此isAlive可能会失败,因为线程 尚未 激活。尝试在thread.start()和thread.isAlive()之间添加一些等待时间

  • 最近我正在学习Java8个特性,所以我从lambda表达式开始,然后我遇到了Java流API,现在我正在尝试围绕流API中的方法,它们是如何工作的? 我对lambda表达式的理解是,如果我们想将lambda表达式传递给该方法,那么我们需要使用单个未实现的方法(Java 8接口可以有默认实现)创建一个与lambda表达式的签名匹配的接口。然后,传递lambda表达式的方法可以通过调用接口方法来执行l