概述
在看多线程这块,突然有个想法,把synchronized关键字直接加到run方法上,会有什么效果。以售票为例,结果就出问题了。
MyRunnable m = new MyRunnable();
Thread t1 = new Thread(m,"1");
Thread t2 = new Thread(m,"2");
Thread t3 = new Thread(m,"3");
Thread t4 = new Thread(m,"4");
Thread t5 = new Thread(m,"5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
private int tickets = 2000;
@Override
public synchronized void run(){
while(true){
try{
if(tickets>0){
try {
Thread.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
System.err.println("窗口"+Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
}
}catch(Exception e){
e.printStackTrace();
}
}
}
结果:
效果就是只有一个线程执行,其余线程不执行。后来查了一下,被synchronized关键字修饰的方法,任何时候最多只能被一个线程执行。问题应该就出在这里。当一开始其中一个线程抢到执行权后,由于该方法中有一个while循环一直执行,所以该线程就一直执行,直到结束,退出方法,其他线程才有机会获得执行权,但该例子中此时程序已经执行结束了。一直处于等待状态。
private int tickets = 100;
Lock lock = new ReentrantLock();
@Override
public
void run() {
while(true){
try{
lock.lock();
if(tickets>0){
try{
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
}
System.err.println("窗口"+Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
}
}catch (Exception e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
}
或者:
Object o = new Object();
@Override
public
void run(){
while(true){
synchronized(o){
try{
if(tickets>0){
try {
Thread.sleep(300);
} catch (Exception e) {
e.printStackTrace();
}
System.err.println("窗口"+Thread.currentThread().getName()+
"正在出售第"+(tickets--)+"张票");
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
将之前的代码改为上面代码执行就正常了。总之,就是把同步锁加在while循环内就可以了,这样每进行一次while循环,其他线程都有机会获得锁对象。
结果:
由于sleep时间短,效果不是很明显
最后
以上就是典雅八宝粥为你收集整理的synchronized方法的全部内容,希望文章能够帮你解决synchronized方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复