1.springmvc,servlet都是单例模式,除非储存对象
2.无状态对象是线程安全的,无状态对象:没有实例对象,并且保持对象的
3.java 用synchronized同步锁控制操作,一般synchronized要加static,如果没有static,当你多线程的时候,会变成线程关注的是自己对象的锁==2个线程有2把不同的锁,不安全了。所有一般是public static sychronized xx()。线程初始化的时候已经加载了这个函数了。
sychronized xx()是实例函数的锁,而static sychronized xx()是类的锁
上面我说的有点乱,主要是针对这种情况的:
Thread thread1=new Thread(new Sy());
Thread thread2=new Thread(new Sy());
这样创建2个不同线程,如果能sychronized xx()的话会出错,必须static sychronized xx()
如果你是
Sy synchronized1=new Sy();
Thread thread1=new Thread(synchronized1);
Thread thread2=new Thread(synchronized1);
这样是创建2个线程,但是他们都指向一个Runnable接口实例!!!
4.lock 也可以锁住对象。
private Lock lock = new ReentrantLock();
lock.lock();
结束时解锁lock.unlock();
lock和synchonized区别:lock可以用trylock(),在没有获取锁的时候进行其他操作,不像synchonized一直等待
5.高并发对象同步操作
6.static声明对象在多线程中可能出现线程不安全,因为可能多次被实例化
7.volatile关键字解决可见 性问题,但是代替不了锁的作用
8.sychronized例子
package test;
public class Sy implements Runnable{
private static int num;
public Sy() {
this.num=100;
}
//不能在线程run方法加sychronized!!!
public void run() {
try {
for(int i=0;i<5;i++)
synchronized(this){
num--;
System.out.println(Thread.currentThread().getName()+" "+"num:"+num);
Thread.sleep(1000);
};
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这里也有一个要注意的,就是不要在run函数里面定义操作,虽然说已经有锁定实例函数,但是操作起来线程里面代码执行可能输出慢,会导致输出结果出错。如下面:
public static synchronized void num(){
num--;
}
public void run() {
for(int i=0;i<40;i++){
num();
System.out.println(Thread.currentThread().getName()+" "+"num:"+num);
}
package test;
public class test {
public static void main(String[] args) {
Sy synchronized1=new Sy();
Thread thread1=new Thread(synchronized1);
Thread thread2=new Thread(synchronized1);
//这里要注意不能写成new Sy(),不然就是新建一个新的线程,里面num由初始化为10!!!
thread1.start();
thread2.start();
}
}
.