java面试刷题,java面试题刷题

  java面试刷题,java面试题刷题

  如何解决写爬虫IP受阻的问题?立即使用。

  我们先来看看题目内容:

  (学习视频分享:java视频教程)

  公共类TestSync2实现Runnable {

  int b=100

  同步void m1()引发InterruptedException {

  b=1000

  thread . sleep(500);//6

  system . out . println( b= b);

  }

  同步的void m2()引发了InterruptedException {

  thread . sleep(250);//5

  b=2000

  }

  公共静态void main(String[] args)引发InterruptedException {

  test sync 2 TT=new test sync 2();

  螺纹t=新螺纹(TT);//1

  t . start();//2

  TT . m2();//3

  System.out.println(主线程b= TT . b);//4

  }

  @覆盖

  公共无效运行(){

  尝试{

  m1();

  } catch (InterruptedException e) {

  e . printstacktrace();

  }

  }

  }这个程序的输出结果?

  程序输出结果

  主螺纹b=2000

  b=1000

  或者

  主线程b=1000

  B=1000调查知识点

  同步实例锁。

  并发下的内存可见性。

  (更多相关面试问题推荐:java面试问答)

  在java中,多线程程序是最难理解和调试的,很多时候执行结果并没有我们想象的那么好。所以java的多线程特别难。我依稀记得大学的时候考C语言二级的时候,问了最后输出结果关于题是什么符合很多其他的重点。这类问题想带一些关于运算符优先级和组合的问题。背下来就可以了,但是java多线程还是需要很好的理解。靠背不好。

  我们先来简单分析一下:

  这个话题涉及两个线程(主线程,子线程),关键词涉及synchronized,Thread.sleep

  synchronized这个关键词还是比较复杂的(可能有时候理解不到位,所以上面的题目会有点误人子弟)。他的功能是实现线程同步(实现线程同步的方法有很多种,不过只是后续文章会讲到其他的,需要研究一下Doug Lea大神的一些实现)。他的工作是锁定需要同步的代码,使得一次只能有一个线程进入同步块(实际上是一种悲观的策略),保证线程只记住安全。

  通用关键字synchronized的用法

  指定锁对象:锁定给定的对象,给定对象的锁在输入同步代码之前需要是活动的。直接作用于实例的方法:相当于锁定了当前实例,在输入同步代码之前要获取当前实例的锁。直接作用在静态方法上:相当于锁定了当前类,在进入同步代码之前要获取当前类的锁。

  上述代码的同步使用实际上属于第二种情况。直接作用于实例的方法:相当于锁定了当前实例,在输入同步代码之前要获取当前实例的锁。

  可能的误解

  因为我们不懂synchronized,因为很多时候我们多线程都是操作一个synchronized的方法。当两个线程调用两个不同的同步方法时,我们认为没关系。这种想法是错误的。直接作用于实例的方法:相当于锁定了当前实例,在输入同步代码之前要获取当前实例的锁。如果调用同步方法。对方调用普通方法也没关系,两者没有等待关系。

  这些对于后面的分析非常有用。

  线程.睡眠

  使当前线程(即调用此方法的线程)暂停执行一段时间,以便其他线程有机会继续执行,但它不释放对象锁。也就是说,如果synchronized同步得很快,其他线程仍然无法访问共享数据。注意这个方法可以捕捉异常,这对后面的分析非常有用。具体可参考我的系统学习java高并发系列二。

  分析过程:

  Java是从main方法执行的。上面说有2个线程,但是在这里修改线程优先级是没有用的。优先级只是在两个程序还没有执行的时候。现在,这段代码一执行,主线程main就被执行了。对于属性变量int b=100,不会因为使用synchronized而出现可见性问题(不需要使用volatile声明)。当执行步骤1时(线程t=新线程(TT));//1)线程处于新状态,还没有开始工作。

  当执行步骤2时(t . start();//2)调用start方法时,线程才真正启动,进入可运行状态。runnable状态表示可以执行,一切准备就绪,但并不意味着必须在cpu上执行。实际执行与否取决于服务cpu的调度。这里,执行三个步骤时,必须先获得锁(因为start需要调用native方法,使用完成后一切就绪,但不代表必须在cpu上执行。是否实际执行取决于服务cpu的调度,然后会调用run方法,执行m1方法)。

  其实这里的两个同步方法中的Thread.sheep要么是无所谓,要么估计会让混淆更加困难。当执行步骤3时,子线程实际上很快就准备好了,但是由于synchronized的存在,它作用于同一个对象,子线程不得不等待。因为main方法中的执行顺序是顺序的,所以必须在步骤3完成之后才能到步骤4,而且因为步骤3的完成,子线程可以执行m1。

  有一个谁先得到多线程的问题。如果四步先得到,那么主线程b=2000。如果子线程m1得到了,可能是B已经被赋值为1000,也可能是主线程b=1000或者主线程b=2000在四步赋值之前输出。这里如果去掉六个步骤,不确定b=执行在前,主线程B=执行在前。但是因为6步的存在,不管怎样,主线程b=都在前面,所以要看是等于1000还是2000。之后b=1000就固定了。

  一些多线程建议

  线程也是很珍贵的,所以推荐使用线程池,这种方式应用广泛。后面分享就显得尤为重要,需要心中有数。给线程命名。在线cpu高的时候,需要使用高级jstack。有名字就方便多了。多线程要特别注意线程安全,也要知道什么是jdk线程安全,这样在使用的时候就不会出现莫名其妙的问题。

  后续文章中也有一些技巧可以分享。多线程特别重要,也特别难。希望大家多多关注。

  多线程的一些调试技巧

  由于断点的原因,所有线程在通过断点时都需要停止,使得这个点不断被打破。很难受。eclispe中有条件断点,满足条件就可以停止,这样就方便了。

  推荐:java入门教程。这是一个很难的java面试问题吗?更多详情请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: