线程的同步与死锁

线程的同步与死锁
在多线程的开发中,同步与死锁的概念非常重要,需要明白:
1.哪里需要同步
2.如何实现同步,代码了解即可
3.以及实现同步之后会有哪些副作用,了解代码并不要求完整的编写,但概念必须清楚。

具体内容
问题的引出:以买火车票为例,不管任何购买方式,一趟接车的票数是固定的。
public class synRunnable {
public static void main(String[] args) {
myThread mt = new myThread(); //定义线程对象
Thread t1 = new Thread(mt); //定义Thread对象
Thread t2 = new Thread(mt);
Thread t3 = new Thread(mt);

    t1.start();
    t2.start();
    t3.start();
}

}

class myThread implements Runnable{
private int ticket = 5; //设一同有五张票
public void run() {
for(int i = 0;i < 100;i++) {
if(ticket > 0) {
try {
Thread.sleep(300);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(“买票:ticket = ” + ticket–);
}
}
运行结果:买票:ticket = 5
买票:ticket = 4
买票:ticket = 3
买票:ticket = 2
买票:ticket = 1
买票:ticket = 0
买票:ticket = -1
出现错误,如果想解决此类问题,必须使用线程同步

同步代码块
之前已介绍过了代码块分为四种:
1.普通代码块,是直接定义在方法之中
2.代码块:是直接定义在类中的,优先于构造方法,重复调用
3.静态块:是使用static关键字声明,优先于构造块执行

在代码块上加上“synchronized”关键字的话,则此代码块就称为同步代码块
格式:
synchronized(同步对象){
需要同步的对象

同步的时候必须指明同步的对象,一般情况下会将当前对象作为同步对象,使用this表示。
public class synRunnable {
public static void main(String[] args) {
myThread mt = new myThread(); //定义线程对象
Thread t1 = new Thread(mt); //定义Thread对象
Thread t2 = new Thread(mt);
Thread t3 = new Thread(mt);

    t1.start();
    t2.start();
    t3.start();
}

}

class myThread implements Runnable{
private int ticket = 5; //设一同有五张票
public void run() {
for(int i = 0;i < 100;i++) {
synchronized(this) {
if(ticket > 0) {
try {
Thread.sleep(300);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(“买票:ticket = ” + ticket–);
}
}
}
}
}
运行结果:
买票:ticket = 5
买票:ticket = 4
买票:ticket = 3
买票:ticket = 2
买票:ticket = 1
从运行结果来看,加入同步操作,所以不会产生负数出现的情况,但是运行效率明显降低

同步方法
除了可以将需要的代码设置成同步代码块之外,也可以使用synchronized关键字将一个方法声明成同步方法
格式:
synchronized 方法返回值 方法名称(参数列表){}

public class synRunnable {
public static void main(String[] args) {
myThread mt = new myThread(); //定义线程对象
Thread t1 = new Thread(mt); //定义Thread对象
Thread t2 = new Thread(mt);
Thread t3 = new Thread(mt);

    t1.start();
    t2.start();
    t3.start();
}

}

class myThread implements Runnable{
private int ticket = 5; //设一同有五张票
public void run() {
for(int i = 0;i < 100;i++) {
this.sale(); //调用同步方法

    }
  }
public synchronized void sale() {     //声明同步方法
    if(ticket > 0) {
        try {
            Thread.sleep(300);    //加入延迟 
        }catch(InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("买票:ticket = " + ticket--);
    }
}

}
运行效果和上面一样,所以证明两种方法效果一样。

死锁
**程序中过多的操作会产生死锁
资源共享时需要进行同步操作**

public class ThreadDeadLock implements Runnable {
private static Zhangsan zs = new Zhangsan(); //实例化static型对象
private static Lisi ls = new Lisi(); //实例化static型对象

private boolean flag = false;

public void run() {
    if(flag) {
        synchronized(zs) {
            zs.say();
            try {
                Thread.sleep(500);
            }catch(InterruptedException e) {
                e.printStackTrace();
            }
            synchronized(ls) {
                zs.get();
            }
        }
    }else {
        synchronized(ls) {
            ls.say();
            try {
                Thread.sleep(500);
            }catch(InterruptedException e) {
                e.printStackTrace();
            }
            synchronized(zs) {
                ls.get();
            }
        }
    }
}
public static void main(String[] args) {
    ThreadDeadLock t1 = new ThreadDeadLock();    
    ThreadDeadLock t2 = new ThreadDeadLock();

    t1.flag = true;
    t2.flag = false;

    Thread thA = new Thread(t1);
    Thread thB = new Thread(t2);

    thA.start();
    thB.start();
}

}

class Zhangsan{
public void say() {
System.out.println(“张三对李四说:你给我画,我就把书给你”);
}

public void get() {
    System.out.println("张三得到画了");
}

}

class Lisi{
public void say() {
System.out.println(“李四对张三说:你给我书,我就把画给你”);
}
public void get() {
System.out.println(“李四得到书了”);
}
}
运行结果:
张三对李四说:你给我画,我就把书给你
李四对张三说:你给我书,我就把画给你
以上就是死锁状态,都在互相等待着对方的回答

总结
1.多个线程在访问同一资源需要进行同步操作
2.同步使用synchronized关键字完成,分为同步代码块和同步方法
3.过多的同步有可能造成死锁的产生,死锁是在程序运行时的一种表现状态,只要了解其产生原理即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值