Java多线程(1)——同步机制

 

创建线程的两种方式:

1,extends Thread

2.  implements Runnable

两者的区别:http://blog.csdn.net/michellehsiao/article/details/7639788

我们稍作总结:

1、Runnable适合于多个相同程序代码线程去处理统一资源的情况,把虚拟的cpu(线程)同程序的代码,数据有效分离,较好体现面向对象的编程的思想

2、Runnable可以避免由于java的单继承机制带来的局限。可以再继承其他类的同时,还能实现多线程的功能。( Java 编程语言只允许一个类有一个父类。同时,某些程序员避免从 Thread 类导出,因为它强加了类层次。对于这种情况,就要 runnable 接口)

3、Runnable能增加程序的健壮性。代码能够被多个线程共享。

下面我们简单看一个实现Runnable接口的多线程

class Demo{
    public void run(){
        show();
    }
    public void show(){
        //功能实现
    }
}

class ThreadDemo{
    public static void main(String[] args){
        Demo d= new Demo();
        Thread t1 = new Thread(d);
        Thread t2 = new Thread(d);
        t1.start();
        t2.start();
    }
    
}

在使用线程过程中我们会遇到很多问题,线程同步就是其中之一。接下来,我们要对多线程进行进一步了解(来自传智播客)

需求一:两个储户到银行存钱,每次存100,一共存3次(线程同步)

//两个储户到银行存钱,每次存100,共存3次

class Bank{
    private int sum;
    //同步函数
    private synchronized void add(int num){
        sum = sum + num;
        try{
            Thread.sleep(10);
        }catch(InterruptedException e){
           e.printStack();
        }
        System.out.println("sum="+sum);
    }
    
    /*
      同步代码块
      private Object obj = new Object();
      public void add(int num){
        synchronized(obj){
            sum = sum + num;
            try...
        }
      
      }
    */
}

class Custom implements Runnable{
    private Bank b = new Bank();
    public void run(){
        for(int x=0;x<3;x++){
            b.add(100);
        }
    }
    
}

class BankDemo{
    public static void main(String[] args){
        Custom c = new Custom();
        Thread t1 = new Thread(c);
        Thread t2 = new Thread(c);
        t1.start();
        t2.start();
    }
}

通过这个需求的实现,我们可以看到线程同步的方式可以使用同步函数或同步代码块。线程加锁以后可以保证其运行的一致性。


同步函数的锁是:this

同步代码块的锁是任意的对象

建议使用同步代码块!!(同步函数可以看做同步代码块的简写)

同步的好处:解决了线程的安全问题;

同步的弊端:相对降低了效率,因为同步外的线程都会判断同步锁;

同步的前提:同步中必须有多个线程并使用同一个锁。


我们在刚才的需求实现中使用了同步函数,如果此时的同步函数被static修饰,结果会如何?

我们使用一个卖票的案例来查看

class Ticket implements Runnable{
    private static int num =100;
    boolean flag = true;
    StaticLock sl = new StaticLock();
    public void run(){
        if(flag){
            while(true){
                //错误情况,static同步函数的锁不是this,而是this.getClass()
                //  synchronized(this){
                synchronized(this.getClass()){
                    if(num>0){
                        System.out.println(Thread.currentThread().getName()+"....obj...."+num--);
                    }
                }
            }
        }else{
            while(true){
                sale();
            }
        }
        
    }
    
    public static synchronized void sale(){
        if(num>0){
              System.out.println(Thread.currentThread().getName()+"....obj...."+num--);
        }
    }
    
}

class StaticSynchronizedFunctionDemo{
    public static void main(String[] args){
        Ticket t =new Ticket();
        Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);

		t1.start();
		try{
		    Thread.sleep(10);
		}catch(InterruptedException e){
		    
		}
		t.flag = false;
		t2.start();
    }
    
}
通过编译运行发现使用static synchronized function未使用this作为同步锁,而是this.getClass(),使用其类名对象。


在使用同步机制的使用,要确保锁的唯一性!







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值