java线程:synchronized

简单化问题

synchronized是对要执行的代码区进行同步锁定,不让多个线程对锁定的代码块同时调用,它需要锁对象。它的常用用法一般有两种,一种是对方法进行修饰,比如:public synchronized  void test(String name) {......},另一种是关键区同步,形如synchronized (lock) {......}。对于方法同步来说说,其实相当于用this作为锁对象,也就是说下面这两种代码是相同的:

public   synchronized    void  test(String name, String lock)  {
       
//code

}


public   synchronized    void  test(String name, String lock)  {
       
synchronized (this{
              
//code
       }

}

同步区能否按设计者的思路限定多线程访问,要注意是否使用同一把机锁。如下面的代码

public   class  Test  extends  Thread  {
    
    
private String name = null;
    
private static String lock = "lock";
    
    
public Test(String ss) {
        
super();
        
this.name = ss;
    }
    

    
private Single s = new Single();    
    
    
public void run(){
        
try {
            
synchronized (this{
                System.out.println(name);
                sleep(
500);
                System.out.println(name 
+ ":after sleep 10000 s");
            }


        }
 catch (Exception e) {
            e.printStackTrace();
        }
        
    }


    
public static void main(String[] args) throws Exception {
        
new Test("thread_1").start();        
        
new Test("thread_2").start();    
    }
    
}

 上面代码运行结果是

thread_1
thread_2
thread_1:after sleep 10000 s
thread_2:after sleep 10000 s
线程2并没等候线程1的机锁,因为机锁对象是不同的对象。如将synchronized (this)替换成synchronized (lock),那么运行结果就是我们期望的

thread_1
thread_1:after sleep 10000 s
thread_2
thread_2:after sleep 10000 s

static方法的synchronized

需要注意的是,static方法使用的机锁对象是className.class。

class  Test2  extends  Thread  {
    
public static synchronized void mytest(String name){
        System.out.println(name
+" begin");
        
try {
            Thread.sleep(
500);
        }
 catch (Exception e) {
        }

        System.out.println(name
+" out");
    }

    
    
public void run(){
        mytest(
"Test2");
    }

}


public   class  Test  extends  Thread  {
    
public void run(){
        
synchronized (Test2.class{//如果换成this或者其它机锁,则我们想要的同步机制就不起作用了
            try {
                System.out.println(
"Test");
                sleep(
500);
                System.out.println(
"Test:after sleep 10000 s");

            }
 catch (Exception e) {
                e.printStackTrace();
            }

        }

    }


    
public static void main(String[] args) throws Exception {
        
new Test().start();
        
new Test2().start();
        
/*执行结果是
            Test
            Test:after sleep 10000 s
            Test2 begin
            Test2 out
        
*/

    }
    
}

 

sleep,suspend,resume,wait,notify,notifyall

sleep(static),suspend,resume同属Thread的方法,他们均不会释放机锁。不推荐使用。

wait,notify,notifyAll同属object的方法,会是否锁资源。我们只能对自己拥有的机锁调用wait,notify,如果调用不正确是可以编译通过,但运行时会报IllegalMonitorStateException。

public   void  run() {
        
synchronized (lock) {
            
try {
                System.out.println(name);
                lock.wait();
                System.out.println(name 
+ ":after sleep 10000 s");

            }
 catch (Exception e) {
                e.printStackTrace();
            }

        }

    }


    
public   static   void  main(String[] args)  throws  Exception  {
        Test t 
= new Test("thread_1");        
        t.start();
        Thread.sleep(
500);//保证下面的代码能唤醒线程
        synchronized (lock) {
            lock.notifyAll();
        }

    }
    

 

 

 想到的问题

我们在做web的action的时候,对某些比较耗性能的函数,常使用synchronized对方法进行限制,这需要注意如果acaction是单例模式,这种方法是可以的,但如果没有用单例模式,那么机锁对象action是不同的,也就没有达到设计者所想要的限制了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值