Java连载109-sychronized关键的用途及其注意点、自定义注解

一、synchronized关键字

1.我们修改一下上一次连载中的withdraw方法

  //synchronized关键字添加到成员方法上去可以达到同步内存变量的目的

  public synchronized void withdraw(double money)  {

      double after = this.balance - money;

      try {

        //这里我们故意延迟了一下,可以看出余额不对了

        Thread.sleep(1000);

      }catch(InterruptedException e){

       

      }

      this.setBalance(after);

  }

这两种方法关键字控制的范围更大,后面代码越来越多可能会降低效率,不如精准同步的代码块效率高

线程安全的类举例:StringBuffer\Vector\HashTable

下面讲解一个案例

package com.bjpowernode.java_learning;

​

public class D109_1_SynchronizedMechanism {

  public static void main(String[] args) throws InterruptedException{

    MyClass109 mc = new MyClass109();

    Processer109 p = new Processer109(mc);

    Thread t1 = new Thread(p);

    Thread t2 = new Thread(p);

    t1.setName("t1");

    t2.setName("t2");

    t1.start();

   

    //延迟(保证t1线程先启动,并执行run)

    Thread.sleep(1000);

    t2.start();

  }

​

}

class Processer109 implements Runnable{

  MyClass109 mc;

  public Processer109(MyClass109 mc){

    this.mc = mc;

  }

  public void run() {

    if(Thread.currentThread().getName().equals("t1")) {

      mc.m1();

    }

    if(Thread.currentThread().getName().equals("t2")) {

      mc.m2();

    }

  }

}

class MyClass109{

  public synchronized void m1() {

    //休眠

    try {

      Thread.sleep(1500);

      System.out.println("m1.....");

    } catch(Exception w) {

     

    }

  }

  //m2方法会等m1方法结束,因为t1和t2共享了一个mc,并且m1和m2方法上都这个关键字,共享了一个对象mc

  public synchronized void m2() {

    System.out.println("m2......");

  }

//  //m2方法执行不需要等待m1结束,因为m2方法上没有synchronized

//  public void m2() {

//    System.out.println("m2......");

//  }

}

二、系统注解的使用

package com.bjpowernode.java_learning;

​

import java.util.LinkedList;

​

public class D109_2_SuperClass {

  public static void main(String[] args) {

    SuperClass109 superObj = new SuperClass109();

    superObj.MethodA();//访问了过时的方法,IDE会加上删除线

    System.out.println(superObj.var);//访问过时的域,也会加上删除线

    SubClass109 subObj = new SubClass109();

    subObj.MethodB1();

    //-------------

    //下面的注解用于抑制其下面的语句的编译警告信息

    @SuppressWarnings("rawtypes")

    LinkedList list = new LinkedList();

    //下面两条语句没有加@SuppressWarnings,编译时会出现警告信息

    list.add(123);

    list.add("Beijing");

    for(int i=0;i<2;i++) {

      System.out.println(list.get(i));

    }

   

  }

​

}

class SuperClass109{

  //对var进行注释,表示var已经过时,虽然var已经过时,但是仍然可以用

  @Deprecated

  int var = 125;

  @Deprecated

  public void MethodA() {

    System.out.println("父类中的Method()方法!");

  }

  public void MethodB() {

    System.out.println("父类中的MethodB方法!");

  }

 

}

class SubClass109 extends SuperClass109{

  //@Override

  public void MethodB1(){

    System.out.println("子类重写父类中的方法MethodB()!");

  }

}

​

三、自定义注解

1.自定义注解要使用@interface来声明,会自动继承java.lang.annotation.Annotation接口

2.在定义自定义注解的时候,不可以继承其他的注解和接口,@interface只用来声明一个注解,注解中的每一个方法实际上是声名了一个配置参数。

3.方法的名称就是参数的名称,返回值类型就是参数的类型。返回值的类型只能是基本数据类型、Class、String、Enum。可以通过default关键字声明参数的默认值。

4.语法格式

[public|final]   @interface   注解名{

  注解元素

}

其中,关键字@Interface表示声明一个自定义注解,“注解名”是合法的标识符,“注解元素”是无参数的方法,方法的类型白哦是注解元素的类型。

注解元素的语法格式

 

数据类型   注解元素名()   [default   默认值]

 

如果只有一个注解元素,在注解元素名为value的情况下,在使用的时候就可以不写出注解元素名,只需要直接给出注解值即可。在使用自定义注解的时候,要将自定义注解放在需要注解的前一行或者同一行,并且咋爱自定义注解后的括号中写出注解元素的值。如果使用默认值,则可以不给出纸介质,如果只有一个注解元素并且名为value,只需要给出值,而不需要给出注解元素名。

四、源码:

D109_1_SynchronizedMechanism.java

D109_2_SuperClass.java

https://github.com/ruigege66/Java/blob/master/D109_1_SynchronizedMechanism.java

https://github.com/ruigege66/Java/blob/master/D109_2_SuperClass.java

2.CSDN:https://blog.csdn.net/weixin_44630050

3.博客园:https://www.cnblogs.com/ruigege0000/

4.欢迎关注微信公众号:傅里叶变换,个人公众号,仅用于学习交流,后台回复”礼包“,获取大数据学习资料

 

猜你喜欢

转载自www.cnblogs.com/ruigege0000/p/12688684.html