【开源中国 APP 全新上线】“动弹” 回归、集成大模型对话、畅读技术报告”
servlet是单例,多线程模式,现在想问下,如果再servlet的doGet方法中写个条件,如果参数为一个特定得值,则线程暂停1分钟,然后输出,否则直接输出,然后我用两个不同的浏览器请求时,现请求特定条件的地址,然后浏览器暂停了,在另一个浏览器里请求普通地址,立刻就输出了,没有出现等待的请求,这是为什么啊,虽然tomcat是多线程访问的,但是多线程访问的都是同一个servlet对象啊,之前的对象中线程暂停了,为什么另一个线程调用servlet的时候没有等待那,我用一个java程序模拟这个操作,使用的也是一个对象是单例的,方法中有个特定条件是暂停线程的,用多线程同时访问这个单例对象,结果就会出现都卡住的情况,多线程使用run启动的,不是用start启动,用start启动可能是我测试次数少吧,没有发现,我想问下,tomcat对于这种情况是怎么处理的那?难道说tomcat在用多线程处理servlet的时候会在每个线程中深度拷贝一个临时的servlet对象?虽然servlet是单例的,但是在每个线程中的servlet确实不同的吗?很是疑惑啊
public class SingleClass {
private static SingleClass instance = null;
private SingleClass() { }
public static synchronized SingleClass getInstance() {
if(instance == null) {
instance = new SingleClass();
}
return instance;
}
public void print(int i){
if(i==1){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.err.println("打印出来的是 1");
}else{
System.err.println("打印出来的不是");
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
final SingleClass s=SingleClass.getInstance();
Thread thread= new Thread(new Runnable() {
public void run() {
SingleClass tmp=s;
tmp.print(1);
}
});
thread.run();
Thread thread2=new Thread(new Runnable() {
public void run() {
SingleClass tmp=s;
tmp.print(0);
}
});
thread2.run();
}
}
概念混淆了,单例不等于synchronized
你用run,那不叫启动线程,那叫方法调用;既然是方法调用,那么自然要等上一句执行完后才开始执行后面的语句;
单例的目的是为了让对象唯一,且减少new的次数;但不等于不可以被多个线程同时使用;
首先最重要的一点,Thread用run启动是什么鬼?线程一定要用start启动!
其次,多线程就是多条路,你一条路堵车了,另一条没堵啊,当然会直接过去。
另外,其实你想的大概是只有一个实例,我在用,你应该等我用完才能用。但是,按你这么想,哪还有多线程引发的同步问题?
引用来自“宋贺”的评论
public class SingleClass {
private static SingleClass instance = null;
private SingleClass() { }
public static synchronized SingleClass getInstance() {
if(instance == null) {
instance = new SingleClass();
}
return instance;
}
public void print(int i){
if(i==1){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.err.println("打印出来的是 1");
}else{
System.err.println("打印出来的不是");
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
final SingleClass s=SingleClass.getInstance();
Thread thread= new Thread(new Runnable() {
public void run() {
SingleClass tmp=s;
tmp.print(1);
}
});
thread.run();
Thread thread2=new Thread(new Runnable() {
public void run() {
SingleClass tmp=s;
tmp.print(0);
}
});
thread2.run();
}
}
这是我写的例子,用来模仿多线程下对单例对象访问的,在print方法中加入了对于特定参数判断然后加上休眠的方法,这个例子会出现多线程访问单例对象时print方法中如果有休眠代码了,则其他线程也会进入等待,直到休眠结束,在一块执行