多线程-线程安全-同步代码块

线程安全问题产生的原理

出现了线程安全问题 卖票出现了重复的票

图解

 线程同步

当我们使用多个线程访问同一个资源的时候 且多个线程对资源有写的操作 就容易出现线程安全问题

要解决上诉多线程并发访问一个资源的安全性问题 也就是解决重复票 java中提供了同步机制

(synchronized)来解决

有三种方法来完成同步操作:

1.同步代码块

2.同步方法

3.锁机制

同步代码块

同步代码块:synchronized关键字可以用于方法中的某个区块中 表示这个区块的资源实现互斥访问

格式:

synchronized(同步锁){
        需要同步操作的代码
}

同步锁:

对象的同步锁只是一个感念 可以想象为在对象上标记了一个锁

1.锁对象 可以是任意类型

2.多个线程对象 要使用同一把锁

注意:在任何时候 最多允许一个线程拥有同步锁 谁拿到锁就进入代码块 其他的线程只能在外等着

锁对象作用:把同步代码块锁住 只让一个线程在同步代码块中执行

代码:

package demo19;

public class DemoSynchronized implements Runnable {
//定义一个多个线程共享的票源
private int ricket=100;
//创建锁对象
Object obj = new Object();

//设置线程任务:卖票
@Override
public void run() {
//使用死循环 让卖票操作重复执行
while (true){

//同步代码块
synchronized (obj){
//加入线程休眠
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//先判断票是否存在
if (ricket==0){
break;
}

//票存在 买票 ticket--
System.out.println(Thread.currentThread().getName()+"--->正在买第"+ricket+"张票");
ricket--;
}
}
}
}

class test07{
public static void main(String[] args) {
//创建实现类对象
DemoSynchronized ticket = new DemoSynchronized();
//实现线程执行
/*
因为有两张售票口所有要进行出售
*/
new Thread(ticket).start();
new Thread(ticket).start();
}
}

运行结果:‘

 同步锁的原理:

使用了一个锁对象 这个锁对象叫做同步锁 也叫对象锁  也叫对象监视器

2个线程一起抢夺cpu的执行权 谁抢到了谁执行run方法进行买票

比如:

  • 第一个线程抢到了cpu的执行权 执行run方法 遇到代码块这时第一个线程会检查同步代码块是否有锁对象
    • 发现有就会获取锁对象 进入到同步中执行
  • 第二个线程抢到了cpu的执行权 执行run方法 遇到代码块 这时第二个线程会检查同步代码块是否有锁对象
    • 发现没有 就会进入堵塞状态 会一直到第一个线程执行完将锁对象还给同步代码块时 第二个线程才执行
总结:同步中的线程 没有执行完毕不会释放锁 同步外的线程没有锁进不去同步
posted @ 2022-10-17 10:21  想见玺1面  阅读(33)  评论(0编辑  收藏  举报