线程同步锁&死锁

1 篇文章 0 订阅

线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。什么是多线程呢?即就是一个程序中有多个线程在同时执行。


单线程:即,若有多个任务,只能依次进行。比如去银行取钱,一个ATM机只能排队操作。
多线程:多个任务可以同时进行,例如,银行两个ATM机同时进行存取款。


程序运行原理

分时调度:

所有线程轮流使用CPU,平均分配每个线程使用CPU的使用时间。

抢占式调度:

优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。


线程安全

如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

/**
 * @Description:
 * @Author: Mr'Sun
 */
public class Test {
    public static void main(String[] args) {
   		//new 一个票,被4个窗口共享
        Ticket ticket = new Ticket();
        new Thread(ticket,"窗口1").start();
        new Thread(ticket,"窗口2").start();
        new Thread(ticket,"窗口3").start();
        new Thread(ticket,"窗口4").start();
    }
}

/**
 * 实现Runnable的代码
 */
class Ticket implements  Runnable {
    //设票数为10
    int ticket=10;
    @Override
    public void run() {
        while (true){
            if (ticket>0){
                try {
                    Thread.sleep(1000);
                }catch (Exception e){
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"正在售票:"+ticket--);
            }
        }

    }
}
**********************************
run:
窗口4正在售票:2
窗口2正在售票:3
窗口3正在售票:1
窗口1正在售票:0
窗口2正在售票:-2
窗口4正在售票:-1

结果出现了0和负数,这就涉及到了线程安全的问题,
加同步锁 synchronized(Object o){....}  o可以是任意对象。

加同步锁后的代码:

class Ticket implements  Runnable {
    //设票数为10
    int ticket=5;
    @Override
    public void run() {
        while (true){
           synchronized (this){
               if (ticket>0){
                   try {
                       Thread.sleep(1);
                   }catch (Exception e){
                       e.printStackTrace();
                   }
                   System.out.println(Thread.currentThread().getName()+"正在售票:"+ticket--);
               }
           }
        }
    }
}
************************
run:
窗口1正在售票:5
窗口4正在售票:4
窗口4正在售票:3
窗口4正在售票:2
窗口4正在售票:1

ps:加了同步锁就相当于把被锁住的代码块一次性只能给一个线程调用

线程死锁:

同步锁使用的弊端:当线程任务中出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步。这时容易引发一种现象:程序出现无限等待,这种现象我们称为死锁。这种情况能避免就避免掉。

 synchronized (A锁){
  synchronized (B锁){
	  }
  }
public class Test {
    //创建两个锁,A锁住厕所坑位,B锁住手纸
    public static Object locaA = new Object();
    public static Object locaB = new Object();

    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(ticket, "A").start();
        new Thread(ticket, "B").start();

    }
}
class Ticket implements Runnable {
    //获取随机数0-1
    int x = new Random().nextInt(1);
    @Override
    public void run() {
        while (true) {
            if (x % 2 == 0) {
                synchronized (Test.locaA) {
                    System.out.println(Thread.currentThread().getName() + "获得蹲坑");
                    synchronized (Test.locaB) {
                        System.out.println(Thread.currentThread().getName() + "获得手纸");

                    }
                }
            } else {
                synchronized (Test.locaB) {
                    System.out.println(Thread.currentThread().getName() + "获得蹲坑");
                    synchronized (Test.locaA) {
                        System.out.println(Thread.currentThread().getName() + "获得手纸");
                    }
                }
            }
            x++;
        }
    }
}
****************
run:
A获得蹲坑
A获得手纸
B获得蹲坑
A获得手纸

当其中一个人获得坑位,在获得手纸,程序才能进行下去。
一旦A获得了坑位,而CPU让B获得了手纸,结果A需要手纸才能离开,
而B需要坑位才能进去。所以就互相锁住了(死锁)。

等待唤醒机制

线程之间的通信:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同。通过一定的手段使各个线程能有效的利用资源。而这种手段即等待唤醒机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值