java如何制造死锁_Java编程之多线程死锁与线程间通信简单实现代码

死锁定义

死锁是指两个或者多个线程被永久阻塞的一种局面,产生的前提是要有两个或两个以上的线程,并且来操作两个或者多个以上的共同资源;我的理解是用两个线程来举例,现有线程A和B同时操作两个共同资源a和b,A操作a的时候上锁LockA,继续执行的时候,A还需要LockB进行下面的操作,这个时候b资源在被B线程操作,刚好被上了锁LockB,假如此时线程B刚好释放了LockB则没有问题,但没有释放LockB锁的时候,线程A和B形成了对LockB锁资源的争夺,从而造成阻塞,形成死锁;具体其死锁代码如下:

public class MyDeadLockTest {

public static void main(String[] args){

Object obj1 = new Object();

Thread thread1 = new Thread(new DeadRes(true,obj1));

Thread thread2 = new Thread(new DeadRes(false,obj1));

thread1.start();

thread2.start();

}

}

class DeadRes implements Runnable{

boolean flag;

Object obj;

public DeadRes(boolean flag, Object obj1) {

this.flag = flag;

this.obj = obj1;

}

@Override

public void run() {

if(flag){

synchronized (DeadRes.class){

System.out.println(Thread.currentThread().getName()+" acquie lock is DeadRes.class");

synchronized (obj){

System.out.println(Thread.currentThread().getName()+" acquie lock is obj");

}

}

}else{

synchronized (obj){

System.out.println(Thread.currentThread().getName()+" acquie lock is obj");

synchronized (DeadRes.class){

System.out.println(Thread.currentThread().getName()+" acquie lock is DeadRes.class");

}

}

}

}

}

执行结果如下图:

Thread-1 acquie lock is obj

Thread-0 acquie lock is DeadRes.class

当然每次执行的结果不一样,有可能是一种和谐状态,没有发生死锁,此时为保证每次死锁,可以让run()方法中,执行while(true)循环,这样保证了每次必定发生死锁;当然实际应用中,我们应该尽量避免死锁,当有多线程操作多个共同资源的时候,避免发生同一锁对象的同步嵌套。

线程间的通讯—-生产者与消费者模式

1、让两个线程交替进行操作,当生产了一个数字后,紧接着消费一个,首先采用Object对象中的wait-notify来实现,具体代码如下:

public class ThreadProConsume {

public static void main(String[] args){

Product product = new Product();

Thread thread1 = new Thread(new Producer(product));

Thread thread2 = new Thread(new Consumer(product));

thread1.start();

thread2.start();

}

}

class Product{

String name;

private int count = 1;

boolean flag = false;

public synchronized void set(String name){

if(flag){

try {

this.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

this.name = name +"--"+count++;

flag = true;

System.out.println(Thread.currentThread().getName()+" produce num : "+this.name);

this.notify();

}

public synchronized void out(){

if(!flag){

try {

this.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(Thread.currentThread().getName()+" consume num is : "+this.name);

flag = false;

this.notify();

}

}

class Producer implements Runnable{

Product res;

public Producer(Product product) {

this.res = product;

}

@Override

public void run() {

while(true){

res.set("guyue");

}

}

}

class Consumer implements Runnable{

Product res;

public Consumer(Product product) {

this.res = product;

}

@Override

public void run() {

while(true){

res.out();

}

}

}

执行结果如图:

Thread-1 consume num is : guyue--3938

Thread-0 produce num : guyue--3939

Thread-1 consume num is : guyue--3939

Thread-0 produce num : guyue--3940

Thread-1 consume num is : guyue--3940

Thread-0 produce num : guyue--3941

Thread-1 consume num is : guyue--3941

当超过两个以上线程操作的时候,这里需要在set()与out()方法中的if判断改为while,并且notif方法,改为notifyAll(),这样多个线程操作的时候,便可以交替进行,具体代码如下:

public class ThreadProConsume {

public static void main(String[] args){

Product product = new Product();

Thread thread1 = new Thread(new Producer(product));

Thread thread3 = new Thread(new Producer(product));

Thread thread2 = new Thread(new Consumer(product));

Thread thread4 = new Thread(new Consumer(product));

thread1.start();

thread3.start();

thread2.start();

thread4.start();

}

}

class Product{

String name;

private int count = 1;

boolean flag = false;

public synchronized void set(String name){

while(flag){

try {

this.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

this.name = name +"--"+count++;

flag = true;

System.out.println(Thread.currentThread().getName()+" produce num : "+this.name);

this.notifyAll();

}

public synchronized void out(){

while (!flag){

try {

this.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(Thread.currentThread().getName()+" consume num is : "+this.name);

flag = false;

this.notifyAll();

}

}

执行结果如下:

Thread-0 produce num : guyue--50325

Thread-2 consume num is : guyue--50325

Thread-1 produce num : guyue--50326

Thread-3 consume num is : guyue--50326

Thread-0 produce num : guyue--50327

Thread-2 consume num is : guyue--50327

Thread-1 produce num : guyue--50328

Thread-3 consume num is : guyue--50328

2、采用Lock-Condition方法实现如下:

class Product{

String name;

private int count = 1;

boolean flag = false;

Lock lock = new ReentrantLock();

Condition conditon = lock.newCondition();

public void set(String name){

try{

lock.lock();

while(flag){

conditon.await();

}

this.name = name +"--"+count++;

flag = true;

System.out.println(Thread.currentThread().getName()+" produce num : "+this.name);

conditon.signalAll();

}catch (Exception e){

}finally {

lock.unlock();

}

}

public void out(){

try{

lock.lock();

while(!flag){

conditon.await();

}

flag = false;

System.out.println(Thread.currentThread().getName()+" consumer num is : "+this.name);

conditon.signalAll();

}catch (Exception e){

}finally {

lock.unlock();

}

}

}

执行结果如下:

Thread-0 produce num : guyue--20305

Thread-3 consumer num is : guyue--20305

Thread-1 produce num : guyue--20306

Thread-2 consumer num is : guyue--20306

Thread-0 produce num : guyue--20307

Thread-3 consumer num is : guyue--20307

Thread-1 produce num : guyue--20308

Thread-2 consumer num is : guyue--20308

以上就是本文关于Java编程之多线程死锁与线程间通信简单实现代码的全部内容,希望对大家有所帮助。关于Java多线程以及线程间通信的例子,本站还有几篇文章可以参考:

如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值