黑马程序员——Java基础——多线程的同步、死锁和等待唤醒机制

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

在线程中,有时候会出现安全问题,就是一个线程的代码还没执行完,CPU就把执行权分配给了其他线程,导致数据出现错误。这些问题我们应该怎么解决呢?
我们可以用到同步来解决。它能让一个线程执行完,在执行过程中,其他线程不可以参与执行。
同步的关键字是 synchronized
同步包括两方面,可以是同步代码块,也可以是同步函数。

第一种,同步代码块:格式如下
synchronized ( 对象 )
{
需要被同步的代码;
}

这里的对象可以是任意对象,譬如 new Object ( ) ,它相当于一个锁。

第二种,同步函数。
其实就是所需要同步的函数用 synchronized 关键字修饰。
同步函数使用的锁是 this

有特殊情况,如果同步函数被静态修饰后,使用的锁是该方法所在类的字节码文件对象。 (类名 . class)

死锁:同步中嵌套同步,多个线程间相互占用着锁,等待对方的锁运行,导致线程都停滞不动的情况。我们要避免这种情况的发生。
譬如下面就是一个死锁的例子:

public class DeadLockTest {
    public static void main(String[] args){
        DeadLock d1=new DeadLock(true);
        DeadLock d2=new DeadLock(false);
        Thread t1=new Thread(d1);
        Thread t2=new Thread(d2);
        t1.start();
        t2.start();
    }
}

class DeadLock implements Runnable{
    private boolean flag;
    DeadLock(boolean flag){
        this.flag=flag;
    }

    public void run(){
        if(flag){
            synchronized(Lock.locka){
                System.out.println("if locka");
                synchronized(Lock.lockb){
                    System.out.println("if lockb");
                }
            }
        }else{
            synchronized(Lock.lockb){
                System.out.println("else lockb");
                synchronized(Lock.locka){
                    System.out.println("else locka");
                }
            }
        }
    }
}

class Lock{
    static Object locka=new Object();
    static Object lockb=new Object();
}

等待唤醒机制:
都使用在同步中,因为要对持有锁的线程进行操作。
主要用到的方法有 wait( ) 、notify ( )、notifyAll ( ) 。

public class DengdaiHuanxing2 {
    public static void main(String[] args){
        Rec r=new Rec();        
        new Thread(new Input(r)).start();
        new Thread(new Output(r)).start();
    }
}

class Rec{
    private String name;
    private String sex;
    boolean flag=false;

    public synchronized void setRec(String name,String sex){
        if(flag)
            try{wait();}catch(Exception e){}
        this.name=name;
        this.sex=sex;
        flag=true;
        notify();
    }
    public synchronized void out(){
        if(!flag)
            try{wait();}catch(Exception e){}
        System.out.println(name+"....."+sex);
        flag=false;
        notify();
    }
}

class Input implements Runnable{
    private Rec r;
    Input(Rec r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true){
            if(x==0){
                r.setRec("Mike", "man");
            }else{
                r.setRec("丽丽","女生");
            }
            x=(x+1)%2;
        }
    }
} 

class Output implements Runnable{
    private Rec r;
    Output(Rec r){
        this.r=r;
    }
    public void run(){
        while(true){
            r.out();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值