当多线程并发访问同一个资源的时候会出现线程不安全问题
可以用Therad.sleep(10)来让问题表现得更明显 用来模拟网络延迟
解决多线程并发访问同一个资源的安全问题
方式1.同步代码块 语法
同步锁 /同步监听器/互斥锁
哪个线程拿到锁 哪个线程就进入资源
synchronized()//同步锁 括弧里是监听对象 对于非static就是this 如果是static修饰 那就是 类名.class
{
}
大括弧里的只能有一个线程执行 是共享资原
方式2.同步方法
使用synchronize修饰的方法 不要使用它修饰run 不然一个线程执行完所有的功能
将需要同步的代码放入新的方法中 使用synchronized修饰
public synchronize void doWork()
{
}
synchronize的好处跟坏处
好处:避免多线程同步操作的安全性问题
坏处:使用synchronize后性能会降低
建议尽量减小其作用域
方式3.锁机制
lock接口 机制提供比synchronize更强大的 更多的功能
lock()获取锁
unlock() 解锁
package cn.bdqn.manytread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SafeOfThread extends Thread
{
@Override
synchronized public void run() {
// TODO Auto-generated method stub
super.run();
}
}
class ArraysUtil
{
private ArraysUtil(){}
//private static ArraysUtil instance=new ArraysUtil();//饿汉式单例
/*public static ArraysUtil getInstance()
{
return instance;
}*/
//有线程不安全问题
/* private static ArraysUtil instance=null;//懒汉式单例
public synchronized static ArraysUtil getInstance()
{
if(instance==null)
instance=new ArraysUtil();
return instance;
}*/
/*private static ArraysUtil instance=null;//懒汉式单例
public synchronized static ArraysUtil getInstance()
{
synchronized(ArraysUtil.class){//static 修饰s时使用类名.class
if(instance==null)
instance=new ArraysUtil();
}
return instance;
}*/
private final Lock lock=new ReentrantLock();
try
{
//共享资源
}catch()
{
//异常
}
finally
{
lock.unlock();
}