多线程:synchronized、lock

synchronized作用:通过private关键字来保证数据对象仅可以被方法访问,所以提出同步方法,使进程有序,不会出错。加了synchronized的方法只有获得锁后才能执行,且执行直到结束后才释放,允许其他方法执行。
synchronized的两种使用方法
1.同步方法:锁某一方法,public synchronized 函数名(){}
2.同步代码块:锁定某一方法不够时,可以锁某一块,
public 方法名(){
synchronized(进程操作的变量){具体操作}
}

死锁:多个线程互相抱着对方所需要的资源,形成僵持。

public class TestLock {
    public static void main(String[] args) {
        Makeup g1=new Makeup(0,"白雪公主");
        Makeup g2=new Makeup(1,"王母娘娘");
        g1.start();
        g2.start();
    }
}
//口红
class Lipsticks{}
//镜子
class Mirror{}

class Makeup extends Thread{
    @Override
    public void run() {
        makeup();
    }

    //用static方法保证该资源仅有一份
    static Lipsticks lipsticks=new Lipsticks();
    static Mirror mirror=new Mirror();
    int choice;//进行选择
    String name;//选择人

    Makeup(int choice,String name){//利用构造方法传参
        this.choice=choice;
        this.name=name;
    }
    public void makeup(){
        if (choice==0) synchronized (lipsticks) {
            System.out.println(this.name + "获得口红");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (mirror){
                System.out.println(this.name+"获得镜子");
            }
        }//由于多线程,没有前后关系,使得g1锁住了口红,g2锁住了镜子。
        //导致每个人的下一步都无法进行,这就是死锁,相互拥有对方所需资源。
        else {
            synchronized (mirror) {
                System.out.println(this.name + "获得镜子");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lipsticks){
                    System.out.println(this.name+"获得口号");
                }
            }
        }
    }
}

解决办法:

 public void makeup(){
        if (choice==0) synchronized (lipsticks) {
            System.out.println(this.name + "获得口红");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }//将第二把锁,移出第一把锁内,这样g1锁住口红后,就结束释放了,g2同理
            //均释放出资源。则可执行成功
            synchronized (mirror){
                System.out.println(this.name+"获得镜子");
            }
        }
        else {
            synchronized (mirror) {
                System.out.println(this.name + "获得镜子");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (mirror){
                    System.out.println(this.name+"获得口红");

                }

            }
        }
    }

锁的另一种方式:Lock

import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
    public static void main(String[] args) {
        Method m1=new Method(5);
        new Thread(m1,"张1").start();
        new Thread(m1,"张2").start();
        new Thread(m1,"张3").start();
        new Thread(m1,"张4").start();
        new Thread(m1,"张5").start();
        new Thread(m1,"张6").start();
        new Thread(m1,"张7").start();
        new Thread(m1,"张8").start();
    }
}
class Method implements Runnable{
    int num;
    private final ReentrantLock lock=new ReentrantLock();
    public Method(int num){
        this.num=num;
    }
    @Override
    public void run() {
        try {
            lock.lock();
            if (num!=0){
                System.out.println(Thread.currentThread().getName()+"拿到了"+num--+"章票");
            }
        }finally {
            lock.unlock();
        }
        }
    }

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值