java 同步 死锁_菜鸡的Java笔记 - java 线程的同步与死锁 (同步 synchronization,死锁 deadlock)...

线程的同步与死锁 (同步 synchronization,死锁 deadlock)

多线程的操作方法

1.线程同步的产生与解决

2.死锁的问题

同步问题的的引出

如果要想进行同步的操作,那么很明显就是多个线程需要访问同一资源

范例:以卖票程序为例

packagecn.mysterious.study3;class MyThread implementsRunnable{private int ticket = 5;

@Overridepublic voidrun() {//TODO Auto-generated method stub

for (int i = 0; i < 10; i++) {if (this.ticket > 0) {

System.out.println(Thread.currentThread().getName()+ ",ticket = "+this.ticket --);

}

}

}

}public classStudyThread {public static void main(String[] args) throwsException {

MyThread mt= newMyThread();

Thread t1= new Thread(mt,"票贩子A");

Thread t2= new Thread(mt,"票贩子B");

Thread t3= new Thread(mt,"票贩子C");

t1.start();

t2.start();

t3.start();

}

}

于是下面开始挖掘本程序所存在的问题

范例:观察程序的问题

packagecn.mysterious.study3;class MyThread implementsRunnable{private int ticket = 5;

@Overridepublic voidrun() {//TODO Auto-generated method stub

for (int i = 0; i < 10; i++) {if (this.ticket > 0) {try{

Thread.sleep(100);

}catch(InterruptedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+ ",ticket = "+this.ticket --);

}

}

}

}public classStudyThread {public static void main(String[] args) throwsException {

MyThread mt= newMyThread();

Thread t1= new Thread(mt,"票贩子A");

Thread t2= new Thread(mt,"票贩子B");

Thread t3= new Thread(mt,"票贩子C");

t1.start();

t2.start();

t3.start();

}

}//结果出现了负数

bane这样的操作就属于线程的不同步的操作,所以发现多个线程操作时必须要考虑到资源同步的问题

实现同步操作

整个代码之中发现有一个逻辑上的流程错误了,以上的程序中,将判断是否有票,延迟,卖票分为了三个部分

那么实际上每个线程如果要执行卖票的话,其他线程应该等待当前线程执行完毕后才可以进入

如果要想在若干个代码上实现锁这个概念,那么就需要通过使用同步代码块或者同步方法来解决

1.同步代码块

使用 synchronized 关键字定义的代码块就称为同步代码块,但是在进行同步的时候需要设置有一个同步对象,那么往往可以使用 this 同步当前对象

packagecn.mysterious.study3;class MyThread implementsRunnable{private int ticket = 500;

@Overridepublic voidrun() {//TODO Auto-generated method stub

for (int i = 0; i < 1000; i++) {synchronized (this) {if (this.ticket > 0) {try{

Thread.sleep(1000);

}catch(InterruptedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+ ",ticket = "+this.ticket --);

}

}

}

}

}public classStudyThread {public static void main(String[] args) throwsException {

MyThread mt= newMyThread();

Thread t1= new Thread(mt,"票贩子A");

Thread t2= new Thread(mt,"票贩子B");

Thread t3= new Thread(mt,"票贩子C");

t1.start();

t2.start();

t3.start();

}

}

加入同步之后整个代码执行的速度已经变慢了,而已不像美誉同步的时候那样多个线程一起进入到方法之中

异步的执行速度要快于同步的执行速度,但是异步的操作属于非线程安全的操作,而同步的操作属于线程的安全操作

2.同步方法

但是对于同步操作,除了用于代码块定义之外,也可以在方法上定义同步操作

packagecn.mysterious.study3;class MyThread implementsRunnable{private int ticket = 500;

@Overridepublic voidrun() {//TODO Auto-generated method stub

for (int i = 0; i < 1000; i++) {

sale();

}

}public synchronized void sale(){ //卖票

if (this.ticket > 0) {try{

Thread.sleep(1000);

}catch(InterruptedException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+ ",ticket = "+this.ticket --);

}

}

}public classStudyThread {public static void main(String[] args) throwsException {

MyThread mt= newMyThread();

Thread t1= new Thread(mt,"票贩子A");

Thread t2= new Thread(mt,"票贩子B");

Thread t3= new Thread(mt,"票贩子C");

t1.start();

t2.start();

t3.start();

}

}

在多个线程访问同一资源时一定要考虑到数据的同步问题,同步就使用 synchronized 关键字

死锁分析(了解)

很明显,死锁是一种不确定的状态,对于死锁的操作应该出现的越少越好,下面的代码只是一个死锁的演示,代码不做任何实际的意义

packagecn.mysterious.study3;class Kidnapper{ //绑匪

public synchronized voidsay(Landlord dz){

System.out.println(" 绑匪说:给我3亿美金,放了你儿子!");

dz.get();

}public synchronized voidget(){

System.out.println("绑匪得到钱");

}

}class Landlord{ //地主

public synchronized voidsay(Kidnapper bf){

System.out.println(" 地主说:放了我儿子,再给钱!");

bf.get();

}public synchronized voidget(){

System.out.println("救回.....");

}

}public class StudyThread implementsRunnable{private Kidnapper bf = newKidnapper();private Landlord dz = newLandlord();publicStudyThread (){new Thread(this).start();

dz.say(bf);

}public static void main(String[] args) throwsException {newStudyThread();

}

@Overridepublic voidrun() {//TODO Auto-generated method stub

bf.say(dz);

}

}

面试题:请问多个线程访问同一资源时可能带来什么问题?以及会产生什么样的附加问题?

多个线程访同一资源时必须考虑同步问题,可以使用 synchronized 定义同步代码块或者是同步方法

程序中如果出现过多的同步那么就将产生死锁

总结

如果看见 synchronized 声明的方法,一定有爱记住这是一个同步方法,属于线程安全的操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值