多线程——同步函数的锁的相关问题

时间:2022-05-18 13:04:50
package com.qianfeng.demo01;
/**
* 探讨同步函数的锁是什么?
* 通过两个线程来验证同步函数的锁是什么?
* 这两个线程都在卖票,一个在同步代码块当中卖票,一个在同步函数当中卖票,
* 如果两个线程用到的是同一把锁就会同步,就不会出现卖错票的情况。
*
* 同步函数使用的锁是什么呢?
* 函数被对象所调用,代表调用函数的对象的引用就是this。
* 也就是说同步函数使用的锁就是this。
*
* 同步代码块和同步函数之间有什么区别?
* 1.同步函数比同步代码块写法简单。
* 2.同步函数使用的锁是固定的this,同步代码块使用的锁是任意的对象。
*
* 建议开发的时候,使用同步代码块,因为锁可以是任意的,尤其是需要不同的锁的时候,同步代码块可以解决这个问题。
* */

public class ThreadDemo02 {

public static void main(String[] args) {
SaleTicket st = new SaleTicket();
System.out.println(st.isFlag()); //true
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);

t1.start(); //开启了线程t1,具备执行资格,不一定有执行权利
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
st.setFlag(false);
t2.start(); //t2也具备了执行资格,不一定有执行权利
}
}

class SaleTicket implements Runnable{

private int num = 100;
private Object obj = new Object();
private boolean flag = true;
public void setFlag(boolean flag) {
this.flag = flag;
}
public boolean isFlag() {
return flag;
}
@Override
public void run() {
if (!flag) {
while(true){
synchronized (this) {
if (num>0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"......sale..code..."+num--);
}
}
}
}else {
while(true){
this.show();
}
}
}
//提取同步代码块当中的内容,在同步函数中进行封装;
public synchronized void show(){
if (num>0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"......sale..function..."+num--);
}
}

}