线程之同步方法

线程同步方法:

synchronized修饰方法:

1.非静态方法: 默认的同步监听器对象 this
2.静态方法: 默认的同步监听器对象 是该方法所在类的 Class对象 ooxx.class

若线程是实现方式:
:同步代码块: 同步监听对象可以选 this, 这个方法所在类的Class对象, 选一个不变对象
:同步方法: 此时可以使用synchronized直接修饰 run方法,因为同步监听器 是 this;

class Account {
private double banlance;

public Account(Double d) {
this.banlance = d;

}

public double getBanlance() {
return banlance;
}

public void setBanlance(double banlance) {
this.banlance = banlance;
}
}

class ATM implements Runnable {
private Account a;
private double drawMoney;

public ATM(Account a, double drawMoney) {
this.a = a;
this.drawMoney = drawMoney;
}

@Override
public void run() {
// TODO Auto-generated method stub
synchronized (this) {
/**
* 若同步代码块使用this作为同步监听器对象,那么直有实现Runnable才可以使用
*/
if (a.getBanlance() > drawMoney) {
System.out.println(Thread.currentThread().getName() + "取走"
+ drawMoney + "元");
a.setBanlance(a.getBanlance() - drawMoney);
System.out.println(Thread.currentThread().getName() + "還剩"
+ a.getBanlance() + "元");
} else {
System.out.println(Thread.currentThread().getName() + "余额不足"
+ a.getBanlance());
}
}

}
}

public class DrawMoneyDemo {

public static void main(String[] args) {
// TODO Auto-generated method stub
Account acount = new Account(1000.00);
ATM a = new ATM(acount, 800);
new Thread(a, "A").start();
new Thread(a, "B").start();
}

}

 

 

卖票例子用任意对象修饰,用Object   o

class MyRunnable implements Runnable{
private Integer num=50;
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<200;i++){
sale();
}
}
private Object o = new Object();
public void sale(){
synchronized(o){
if(num>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖出了第"+num--+"张");
}
}
}
}
public class TickDemoSynchByblock {
public static void main(String args[]){
Runnable r=new MyRunnable();
new Thread(r,"A").start();
new Thread(r,"B").start();
new Thread(r,"C").start();
}
}

若线程时继承方式:
:同步代码块: 这个方法所在类的Class对象, 选一个不变对象
:同步方法: 此时不能使用synchronized直接修饰 run方法

请看下方例子

class Account2 {
public double banlacne;
public double getBanlacne() {
return banlacne;
}

public void setBanlacne(double banlacne) {
this.banlacne = banlacne;
}

public Account2(double b) {
this.banlacne = b;
}

public synchronized void drawMoney(double drawMoney) {
// TODO Auto-generated method stub
if (banlacne > drawMoney) {
System.out.println(Thread.currentThread().getName() + "-->,吐出"
+ drawMoney);
setBanlacne(banlacne - drawMoney);
System.out.println(Thread.currentThread().getName() + "剩余"
+ banlacne);
} else {
System.out.println(Thread.currentThread().getName() + "余额不足"
+ getBanlacne());
}
}
}

class ATM2 extends Thread {
private double drawMoney;
private Account2 a;

public ATM2(double drawMoney, Account2 a, String name) {
super(name);
this.drawMoney = drawMoney;
this.a = a;
}

public void run() {
a.drawMoney(drawMoney);
}
}

public class CopyOfDrawMoney {

public static void main(String[] args) {
// TODO Auto-generated method stub
Account2 a = new Account2(1000.00);
new ATM2(800, a, "A").start();
new ATM2(800, a, "B").start();
}

}

取钱的例子,不能用Synchronized 直接修饰run方法

第三种 ReentrantLock

格式:
*
* private final ReentrantLock lock= new ReentrantLock();//创建锁的一个对象
*
* public void m(){
* //进入方法第一件事,上锁
* lock.lock();//获取锁
*
* try{
* //需要同步的代码
* }finally{
* lock.unlock();//解锁,走人
* }
*
*
* }

请看例子

 

 

class Account{
private double banlance;
private final ReentrantLock lock= new ReentrantLock();
public Account(double banlance) {
super();
this.banlance = banlance;
}
public double getBanlance() {
return banlance;
}

public void setBanlance(double banlance) {
this.banlance = banlance;
}
public void drawMoney(double drawMoney ){
lock.lock();   //上锁
try{
if(getBanlance()>=drawMoney){
System.out.println(Thread.currentThread().getName()+"取出"+drawMoney);
setBanlance(getBanlance() - drawMoney);
System.out.println(Thread.currentThread().getName() + "剩余"
+ getBanlance());
} else {
System.out.println(Thread.currentThread().getName() + "余额不足"
+ getBanlance());
}
}finally{
lock.unlock();  // 放锁
}
}
}
class ATM extends Thread{
private Account a;
private double drawMoney;
public ATM(double drawMoney, Account a, String name) {
super(name);
this.drawMoney = drawMoney;
this.a = a;
}

public void run(){
a.drawMoney(drawMoney);
}
}

public class DrawMoneyDemo {

public static void main(String[] args) {
// TODO Auto-generated method stub
Account a = new Account(1000);
new ATM(800, a, "A").start();
new ATM(800, a, "B").start();
}

}

 

 

卖票例子

class MyRunnabl implements Runnable{
private Integer num=50;
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<50;i++){
sale();
}
}
public synchronized void sale(){
if (num > 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出第" + num--
+ "张");
}
}
}

public class TicketDemoSynchByblock2 {

public static void main(String[] args) {
// TODO Auto-generated method stub
MyRunnabl t=new MyRunnabl();
new Thread(t,"A").start();
new Thread(t,"B").start();
new Thread(t,"C").start();
}

}

posted on 2017-07-09 15:15  苏小沫  阅读(216)  评论(0编辑  收藏  举报