Java多线程编程

目的:为了防止多个线程同时访问一个数据对象,对数据造成破坏
作用:确保方法里面的代码一次只由一个线程访问,当被线程访问会加锁,所以其他线程也无法访问,只能等待,当这个线程访问之后(同步方法运行完之后),释放锁,下一个线程(从等待的线程中选取)继续访问,加锁,其他线程等待。

对于同步,一般而言在java代码中需要完成两个操作:
-把竞争访问的资源表示为private。
-同步那些访问资源的代码,使用synchronized关键字来修饰方法或代码块(使用两种方式来实现线程的同步:方法和代码块)

尽量避免嵌套同步块,因为容易引起死锁

多线程同步的例子:银行取钱,一张银行卡500元,一个人在柜台取,一个人在ATM里面取,同步执行,则两个人只有一个人能去除400元,代码中getMoney方法有synchronized代表同步方法,若不加synchronized,则两个人都能取到钱,会出现负数

package cn.com.jlu.demo;

public class SynchronizedDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {

        Bank bank=new Bank();

        ThreadDemo t1=new ThreadDemo(bank);
        t1.start();

        ThreadDemo t2=new ThreadDemo(bank);
        t2.start();
    }

}


//创建线程类
class ThreadDemo extends Thread
{

    private Bank bank=null;

    public ThreadDemo(Bank bank) {
        super();
        this.bank = bank;
    }

    @Override
    public void run() {

        System.out.println("取钱:"+bank.getMoney(400));
    }

}


class Bank
{
    //把竞争访问的资源表示为private。
    private int money=500;

    //num代表要取得钱数,money代表你存的钱数
    //方法加上了synchronized关键字,代表同步方法,线程访问是会上锁,其他的线程需等待
    public synchronized int getMoney(int num)  
    {

        if(num<0)
        {
            return -1;
        }else if(money<0){
            return -2;

        }else if(money-num<0){
            return -3;//取的钱比存的钱多时,报错
        }else
        {

            try {
                Thread.sleep(1000);//模拟取钱的时间1s
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println("剩余:"+(money-=num));

            return num;
        }


    }

}

运行结果
这里写图片描述

同步进程死锁:
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

package cn.com.jlu.demo;

public class DieThreadDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {

        Example example=new Example();

        Thread1 t1=new Thread1(example);
        t1.start();


        Thread2 t2=new Thread2(example);
        t2.start();

    }

}

class Thread1 extends Thread
{
    Example example=null;

    public Thread1(Example example) {
        super();
        this.example = example;
    }

    @Override
    public void run() {

        example.method1();
    }


}

class Thread2 extends Thread
{
    public Thread2(Example example) {
        super();
        this.example = example;
    }

    Example example=null;

    @Override
    public void run() {
        example.method2();
    }

}

class Example
{

    //两个线程,第一个线程有资源a,但是等待资源b,而第二个线程拥有资源b等待资源a

    Object obja=new Object();
    Object objb=new Object();

    public void method1()
    {
        //synchronized修饰代码块,锁定obja,申请objb
        synchronized (obja) {

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            synchronized (objb) {
                System.out.println("method1");  
            }

        }

        }

        public void method2()
        {
            //synchronized修饰代码块,锁定obja,申请objb
            synchronized (objb) {

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                synchronized (obja) {
                    System.out.println("method2");  
                }

            }

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值