java高并发同步问题

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();
	}
}

sychronized(i)--->里面这个是int类型,这样就错了,因为int在java是不可变的,那么你会问i++怎么办,它是新建一个对象赋值给它一个新 的。所有说你每次 都锁住不同的数,会出错。要改成sychroized(类名)

.

你可能感兴趣的:(线程安全,java)