Java多线程编程

    xiaoxiao2021-03-25  103

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

    对于同步,一般而言在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"); } } } }
    转载请注明原文地址: https://ju.6miu.com/read-18313.html

    最新回复(0)