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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。