美文网首页
java 线程安全问题的解决办法 和死锁

java 线程安全问题的解决办法 和死锁

作者: 发光驴子 | 来源:发表于2018-03-08 00:40 被阅读0次

线程安全问题的解决办法

线程 安全问题的解决方案:sun提供了线程同步机制让我们解决这类问题的。

java线程同步机制的方式:
方式一:同步代码块

        同步代码块的格式:
            
            synchronized(锁对象){
                需要被同步的代码...
            }

同步代码块要注意事项:
1. 任意的一个对象都可以做为锁对象。
2. 在同步代码块中调用了sleep方法并不是释放锁对象的。
3. 只有真正存在线程安全问题的时候才使用同步代码块,否则会降低效率的。
4. 多线程操作的锁 对象必须 是唯一共享 的。否则无效。

    class SaleTicket extends Thread{
 static int num = 50;//票数  非静态的成员变量,非静态的成员变量数据是在每个对象中都会维护一份数据的。
 
 static Object o = new Object();

 public SaleTicket(String name) {
    super(name);
}

@Override
public void run() {
    while(true){
        //同步代码块
        synchronized ("锁") {//任意的一个对象都可以做为锁对象。对象为Static,但String特殊,因为字符串就是在字符串常量池中。              
            if(num>0){
                System.out.println(Thread.currentThread().getName()+"售出了第"+num+"号票");
                try {
                    Thread.sleep(100);//在同步代码块中调用了sleep方法并不是释放锁对象的。
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                num--;
            }else{
                System.out.println("售罄了..");
                break;
            }
        }
        
    }
}   


} 


public class Thread_02 {

public static void main(String[] args) {
    String s =new String("abc");
    String str1 = "abc"; 
    System.out.println(str1 ==s);
    //创建三个线程对象,模拟三个窗口
    SaleTicket thread1 = new SaleTicket("窗口1");
    SaleTicket thread2 = new SaleTicket("窗口2");
    SaleTicket thread3 = new SaleTicket("窗口3");
    //开启线程售票
    thread1.start();
    thread2.start();
    thread3.start();
    
}

  }

方式二:同步函数
同步函数就是使用synchronized修饰一个函数。

同步函数要注意的事项 :
    1. 如果是一个非静态的同步函数的锁 对象是this对象(ps:这样会存在锁不住的情况,因为俩个对象调用同一个文件,就会出现俩个锁),如果是静态的同步函数的锁 对象是当前函数所属的类的字节码文件(class对象)。
    2. 同步函数的锁对象是固定的,不能由你来指定 的。


推荐使用: 同步代码块。
    原因:
        1. 同步代码块的锁对象可以由我们随意指定,方便控制。同步函数的锁对象是固定 的,不能由我们来指定。
        2. 同步代码块可以很方便控制需要被同步代码的范围,同步函数必须是整个函数 的所有代码都被同步了。
class BankThread extends Thread{

static  int count = 5000;

public BankThread(String name){
    super(name);
}

@Override  //
public void run() {
    getMoney();//这样也锁定住,但是会造成只能一个人取完全部的钱,因为只有循环结束,才会释放锁
}   


//静态的函数---->函数所属 的类的字节码文件对象--->BankThread.class  唯一的。
public static synchronized  void getMoney(){
    while(true){            
            if(count>0){
                System.out.println(Thread.currentThread().getName()+"取走了1000块,还剩余"+(count-1000)+"元");
                count= count - 1000;
            }else{
                System.out.println("取光了...");
                break;
            }
        
    }
}

 }


  public class Demo1 {

public static void main(String[] args) {
    //创建两个线程对象
    BankThread thread1 = new BankThread("老公");
    BankThread thread2 = new BankThread("老婆");
    //调用start方法开启线程取钱
    thread1.start();
    thread2.start();
    
    
}

}       

出现线程安全问题的根本原因:
1. 存在两个或者两个以上 的线程对象,而且线程之间共享着一个资源。
2. 有多个语句操作了共享资源。

线程的死锁

/*
 * java 中同步机制解决了线程安全问题,但是同时引发死锁现象
 * 
 * 死锁现象:就是 俩个或者俩个以上线程,共同调用俩个或者以上的资源,发生共同等待的状态
 * 
 * 死锁现象的出现的根本原因:
 * 1.存在俩个或者俩个以上的线程
 * 2.存在俩个或者俩个以上的共享资源
 * 
 * 死锁现象的解决方案:没有方案,只能尽量避免发生而已

*/

class DeadLock extends Thread{
    public DeadLock(String name){
        super(name);
    }

    public void run(){
        if("张三".equals(Thread.currentThread().getName())){
            synchronized ("遥控器") {
                System.out.println("张三拿到了遥控器,准备去拿电池!!");
                synchronized ("电池") {
                    System.out.println("张三拿到了遥控器和电池,开始吹空调");
                }
            }
        
        }else if("李四".equals(this.getName())){
            synchronized ("电池") {
                System.out.println("李四拿到了电池,准备去那遥控器");
                synchronized ("遥控器") {
                    System.out.println("李四拿到了遥控器和电池,开始吹空调");
                }
            }
        
        }
    }
}
public class Thread_04 {
    public static void main(String[] args) {
            DeadLock l1=new DeadLock("张三");
        DeadLock l2=new DeadLock("李四");
        l1.start();
        l2.start();
}

}

相关文章

  • java 线程安全问题的解决办法 和死锁

    线程安全问题的解决办法 线程 安全问题的解决方案:sun提供了线程同步机制让我们解决这类问题的。 java线程同步...

  • 线程 6. 死锁

    没有办法解决,只能避免 java同步机制解决了线程安全问题,但是同时也引发了死锁现象。死锁现象如何解决呢: 没法解...

  • 两种方法,让死锁现出原形~~

    多线程一直是java开发的一个难点,有很多问题需要考虑,例如线程安全问题,锁机制性能问题等等。其中死锁是当中很难处...

  • volatile关键字

    线程安全问题 Java多线程带来的一个问题是数据安全问题,判断一段Java代码是否有线程安全问题可从以下几点入手:...

  • Java自学-多线程 死锁

    Java 演示多线程死锁 当业务比较复杂,多线程应用里有可能会发生死锁 步骤 1 : 演示死锁 线程1 首先占有对...

  • Synchronized关键字详解2(对非object持锁)

    4.死锁:同步方法容易造成死锁。Java线程死锁是一个经典的多线程问题,因为不同的线程都在等待根本不可能被释放的锁...

  • java——多线程讲解二

    多线程是多个线程同时对同一个数据执行相同或不同的任务。要注意的是,这样的操作很大可能会出现线程安全问题,和线程死锁...

  • Java锁(悲观、乐观锁、CAS原子操作)

    Java死锁发生的必要条件 Java死锁产生的四个必要条件: 互斥使用,即当一个线程占用了资源,其他线程不能使用。...

  • 线程安全问题

    线程安全问题 本篇主要讲解 线程安全问题,演示什么情况下会出现线程安全问题,以及介绍了 Java内存模型 、vol...

  • 如何去检测死锁

    如何检测死锁 死锁预防 让线程获取锁的顺序一致 死锁检测 jps 查看java 进程信息 jstack +进程号 ...

网友评论

      本文标题:java 线程安全问题的解决办法 和死锁

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