多线程中的线程通信以及死锁问题

来源:互联网 发布:网络追踪命令 编辑:程序博客网 时间:2024/05/20 04:47

多线程中的线程通信问题:

先列出线程中释放锁的操作:

1.当前线程的同步方法、同步代码块执行结束
2.当前线程在同步代码块,同步方法中遇到break、return、终止了该大妈快,方法的执行
3.出现了为处理的error或者exception,导致异常结束
4.当前线程在同步代码块,同步方法中执行了线程对象的wait()方法,当前线程暂停,并释放锁。

线程的通信使用的方法:wait()、notify()、notifyAll()----------这三个方法都是Object里的方法,不是线程中的方法

一个关于线程通信的实例:实现两个储户往同一个账户中交替存钱,每个储户存三次,每次存完打印账户中余额。

共享资源类:Account

public class Account {    int balance;    public Account(){}    //synchronized:同步方法,解决线程中的安全问题    public synchronized void saveMonny(int atm){        notify();//唤醒其他挂起的线程        balance += atm;        try {            Thread.currentThread().sleep(10);//当前线程沉睡10毫秒,放大不加同步锁时的操作        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+":"+balance);        try {            if(balance<6000){                wait();//账户未存满6000,当前线程挂起,并释放锁            }else {                //账户中存满6000,让当前线程执行结束,释放锁            }        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
储户类:Customer

public class Customer implements Runnable{    Account account;    //线程中的共享资源(多个线程共同操作的对象)    public Customer(Account account){        this.account = account;    }    @Override    public void run() {        for(int i=0;i<3;i++){            account.saveMonny(1000);        }    }}
测试类:

public class AccountTest {    public static void main(String[] args) {        Account account = new Account();        Customer customer = new Customer(account);        Thread t1 = new Thread(customer);        Thread t2 = new Thread(customer);        t1.setName("甲");        t2.setName("乙");        t1.start();        t2.start();    }}

运行结果:

这样就利用线程通信实现了甲和乙往同一个账户中交替存钱。


线程中的死锁问题:

  什么是死锁?

不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。

一个死锁的实例:

public class DeadLock {    static StringBuffer s1 = new StringBuffer();    static StringBuffer s2 = new StringBuffer();    public static void main(String[] args) {        new Thread(){            @Override            public void run() {                synchronized (s1){    //当前线程持s1锁,同步代码块走完则释放该锁                    s1.append("A");                    try {                        Thread.currentThread().sleep(10);//当前线程沉睡10毫秒                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    synchronized (s2){  //当前线程再持一把s2锁,但被下面线程拿着,形成死锁                        s2.append("B");                        System.out.println(Thread.currentThread().getName()+":"+s1);                        System.out.println(Thread.currentThread().getName()+":"+s2);                    }                }            }        }.start();        new Thread(){            @Override            public void run() {                synchronized (s2){  //由于之前线程沉睡10毫秒,当前线程拿到s2锁                    s1.append("C");                    try {                        Thread.currentThread().sleep(10);//沉睡10毫秒                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    synchronized (s1){ //需要拿到s1锁,但被上面线程拿着,形成死锁                        s2.append("D");                        System.out.println(Thread.currentThread().getName()+":"+s1);                        System.out.println(Thread.currentThread().getName()+":"+s2);                    }                }            }        }.start();    }}

运行上面程序,会发现程序处于阻塞状态,即两个线程都在等待对方释放自己所需要的同步资源,形成死锁


阅读全文
0 0