美文网首页
多线程(二)

多线程(二)

作者: 菜鸟要逆袭 | 来源:发表于2018-07-22 17:49 被阅读0次

多线程安全

当一个线程进入数据操作的时候,如果其暂时休眠/阻塞/等待状态,其他线程可能会先进行数据操作,从而导致线程不安全的问题

实现线程安全的解决办法(synchronized)

  • 1 使用同步代码块
/*创建售票线程*/
public class Tickets implements Runnable{
  private int ticket = 100;
  private Object obj = new Object();//此对象为同步代码块中传递的任意对象(实质为对象监视器),不要在同步代码块的参数中写入匿名对象,因为线程调用多次就会创建多次,浪费系统资源
  public void run(){
    //线程共享数据,加入同步代码块,保证线程安全
    synchronized(obj){
      while(ticket > 0){
        try{
          Thread.sleep(10);
        }catch(Exception e){
          e.printStackTrace();
        }
        Sop(Thread.currentThread().getName()+" 出售第 "+i+" 张票");
      }
    }
  }
}
/*调用售票线程*/
public class ThreadDemo{
  public static void main(String[] args){
    Tickets tic = new Tickets();
    Thread t1 = new Thread(tic);
    Thread t2 = new Thread(tic);
    Thread t3 = new Thread(tic);
    t1.start();
    t2.start();
    t3.start();
  }
}
同步代码块执行原理图.png
  • 2 使用同步方法
public class Tickets implements Runnable{
  private int ticket = 100;
  public void run(){
    while(true){
        saleTicket();
    }
  }
  //同步方法:将同步代码块的内容提取出来形成同步方法
  public [static] synchronized void saleTicket(){
    if(ticket > 0){
        try{
          Thread.sleep(10);
        }catch(Exception e){
          e.printStackTrace();
        }
        Sop(Thread.currentThread().getName()+" 出售第 "+i+" 张票");
      }
  }

}
/*调用售票线程*/
public class ThreadDemo{
  public static void main(String[] args){
    Tickets tic = new Tickets();
    Thread t1 = new Thread(tic);
    Thread t2 = new Thread(tic);
    Thread t3 = new Thread(tic);
    t1.start();
    t2.start();
    t3.start();
  }
}

小总结
同步非静态方法有锁么?有,同步方法中的对象锁,是本类对象引用的this
同步静态方法有锁么?有,同步非静态方法的对象锁,是本类类名.class

实现线程安全的解决办法(lock)

Lock接口是jdk1.5的新特性

  • 1 代码实现
public class Tickets implements Runnable{
  private int ticket = 100;
  //在类成员变量位置,创建Lock接口的实现类对象
  private Lock lock = new ReentrantLock();
  public void run(){
      while(true){
        //调用Lock接口方法lock()获取锁
        lock.lock();
        if(ticket > 0){
          try{
            Thread.sleep(10);
            Sop(Thread.currentThread().getName()+" 出售第 "+i+" 张票");
          }catch(Exception e){
            e.printStackTrace();
          }finally{
            //调用Lock接口unlock()方法,释放锁
            lock.unlock();
          }
        }
      }
    }
  }
}
public class ThreadDemo{
  public static void main(String[] args){
    Tickets tic = new Tickets();
    Thread t1 = new Thread(tic);
    Thread t2 = new Thread(tic);
    Thread t3 = new Thread(tic);
    t1.start();
    t2.start();
    t3.start();
  }
}

相关文章

网友评论

      本文标题:多线程(二)

      本文链接:https://www.haomeiwen.com/subject/vqnlmftx.html