🍣线程同步锁Synchrosized
通过案例:三人买票,保证不会同时访问一张票,导致买重票。
- 同步锁:同步方法:成员方法
同步代码块:this|类名.class|资源
通过这四种方法实现……
1、普通编写(不使用同步锁)
案例:使用线程实现张三,李四,王五网上一起购买100张票
public class Synchrosized01 implements Runnable{
//定义一百张票
int stack=100;
public static void main(String[] args) {
Synchrosized01 sy=new Synchrosized01();
new Thread(sy,"张三").start();
new Thread(sy,"王五").start();
new Thread(sy,"李四").start();
}
@Override
public void run() {
while(true){
if(stack<=0){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//进行买票
System.out.println(Thread.currentThread().getName()+"买第"+stack+"票");
stack--;
}
}
}
结果:
结果:三个人同时去买票导致数据重读,数据不安全
2、同步成员方法锁
- 通过Synchrosized锁成员方法,实现数据安全
public class Synchrosized02 implements Runnable{
//定义一百张票
int stack=100;
public static void main(String[] args) {
Synchrosized02 sy=new Synchrosized02();
Thread t1=new Thread(sy,"张三");
Thread t2=new Thread(sy,"王五");
Thread t3= new Thread(sy,"李四");
t1.start();
t2.start();
t3.start();
}
@Override
public void run() {
while(true){
if(isOk()){
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//同步成员方法
public synchronized boolean isOk(){
if(stack<=0){
return true;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//进行买票
System.out.println(Thread.currentThread().getName()+"买第"+(stack--)+"票");
return false;
}
}
结果:成功保证了多人买票时,数据的安全性
3、同步块
- 通过同步块,实现数据安全
public class Synchrosized03 implements Runnable{
//定义一百张票
int stack=100;
public static void main(String[] args) {
Synchrosized03 sy=new Synchrosized03();
Thread t1=new Thread(sy,"张三");
Thread t2=new Thread(sy,"王五");
Thread t3= new Thread(sy,"李四");
t1.start();
t2.start();
t3.start();
}
@Override
public void run() {
while(true){
synchronized (this) {
if (stack <= 0) {
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//进行买票
System.out.println(Thread.currentThread().getName() + "买第" + stack + "票");
stack--;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
5、双重判断
- 通过双重判断提高同步块的效率
public class Synchrosized04 implements Runnable{
//定义一百张票
int stack=100;
public static void main(String[] args) {
Synchrosized04 sy=new Synchrosized04();
Thread t1=new Thread(sy,"张三");
Thread t2=new Thread(sy,"王五");
Thread t3= new Thread(sy,"李四");
t1.start();
t2.start();
t3.start();
}
@Override
public void run() {
while(true){
if (stack <= 0) {
break;
}
System.out.println("--------------------------");
System.out.println("--------------------------");
System.out.println("--------------------------");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
if(stack<=0){
break;
}
//进行买票
System.out.println(Thread.currentThread().getName() + "买第" + stack + "票");
stack--;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
6、锁资源
public class Synchrosized06 implements Runnable{
//定义一百张票
Stack stack=new Stack();
public static void main(String[] args) {
Synchrosized04 sy=new Synchrosized04();
Thread t1=new Thread(sy,"张三");
Thread t2=new Thread(sy,"王五");
Thread t3= new Thread(sy,"李四");
t1.start();
t2.start();
t3.start();
}
@Override
public void run() {
while(true){
if (stack.stack <= 0) {
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
if(stack.stack<=0){
break;
}
//进行买票
System.out.println(Thread.currentThread().getName() + "买第" + stack + "票");
stack.stack--;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//定义一个票的类
class Stack{
int stack=100;
}
6、线程版单例模式(同步静态方法锁)
- 通过三个线程获取对象
- 利用同步锁,实现获取同一个地址
public class Synchrosized05 {
//定义一个公共的静态引用成员变量
private static Synchrosized05 s5;
//限制创建对象
private Synchrosized05(){
}
//通过静态方法创建对象
public synchronized static Synchrosized05 sy5(){
Synchrosized05 syn=new Synchrosized05();
//synchronized (Synchrosized05.class){
if(syn.s5==null){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return syn.s5=new Synchrosized05();
}
return syn.s5;
// }
}
//测试
public static void main(String[] args) {
new Thread(()-> System.out.println(Synchrosized05.sy5())).start();
new Thread(()-> System.out.println(Synchrosized05.sy5())).start();
new Thread(()-> System.out.println(Synchrosized05.sy5())).start();
}
}