Java synchronized关键_动力节点Java学院整理

synchronized原理

在java中,每一个对象有且仅有一个同步锁。这也意味着,同步锁是依赖于对象而存在。

当我们调用某对象的synchronized方法时,就获取了该对象的同步锁。例如,synchronized(obj)就获取了“obj这个对象”的同步锁。

不同线程对同步锁的访问是互斥的。也就是说,某时间点,对象的同步锁只能被一个线程获取到!通过同步锁,我们就能在多线程中,实现对“对象/方法”的互斥访问。 例如,现在有两个线程A和线程B,它们都会访问“对象obj的同步锁”。假设,在某一时刻,线程A获取到“obj的同步锁”并在执行一些操作;而此时,线程B也企图获取“obj的同步锁” —— 线程B会获取失败,它必须等待,直到线程A释放了“该对象的同步锁”之后线程B才能获取到“obj的同步锁”从而才可以运行。

synchronized基本规则

我们将synchronized的基本规则总结为下面3条,并通过实例对它们进行说明。

第一条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的该“synchronized方法”或者“synchronized代码块”的访问将被阻塞。

第二条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程仍然可以访问“该对象”的非同步代码块。

第三条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的其他的“synchronized方法”或者“synchronized代码块”的访问将被阻塞。

第一条

当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的该“synchronized方法”或者“synchronized代码块”的访问将被阻塞。

下面是“synchronized代码块”对应的演示程序。

 class MyRunable implements Runnable {
  @Override
  public void run() {
   synchronized(this) {
    try {
     for (int i = 0; i < 5; i++) {
      Thread.sleep(); // 休眠ms
      System.out.println(Thread.currentThread().getName() + " loop " + i);
     }
    } catch (InterruptedException ie) {
    }
   }
  }
 }
public class Demo_ {
  public static void main(String[] args) {
   Runnable demo = new MyRunable();  // 新建“Runnable对象”
   Thread t1 = new Thread(demo, "t1"); // 新建“线程t1”, t1是基于demo这个Runnable对象
  Thread t2 = new Thread(demo, "t2"); // 新建“线程t2”, t2是基于demo这个Runnable对象
   t.start();       // 启动“线程t”
   t.start();       // 启动“线程t”
  }
 }

运行结果:

t1 loop 0
t1 loop 1
t1 loop 2
t1 loop 3
t1 loop 4
t2 loop 0
t2 loop 1
t2 loop 2
t2 loop 3
t2 loop 4

结果说明:

run()方法中存在“synchronized(this)代码块”,而且t1和t2都是基于"demo这个Runnable对象"创建的线程。这就意味着,我们可以将synchronized(this)中的this看作是“demo这个Runnable对象”;因此,线程t1和t2共享“demo对象的同步锁”。所以,当一个线程运行的时候,另外一个线程必须等待“运行线程”释放“demo的同步锁”之后才能运行。
如果你确认,你搞清楚这个问题了。那我们将上面的代码进行修改,然后再运行看看结果怎么样,看看你是否会迷糊。修改后的源码如下:

class MyThread extends Thread {
  public MyThread(String name) {
   super(name);
  }
  @Override
  public void run() {
   synchronized(this) {
    try {
     for (int i = 0; i < 5; i++) {
      Thread.sleep(100); // 休眠100ms
      System.out.println(Thread.currentThread().getName() + " loop " + i);
     }
    } catch (InterruptedException ie) {
    }
   }
  }
 }
 public class Demo1_2 {
  public static void main(String[] args) {
   Thread t1 = new MyThread("t1"); // 新建“线程t1”
  Thread t2 = new MyThread("t2"); // 新建“线程t2”
   t.start();       // 启动“线程t”
   t.start();       // 启动“线程t”
  }
 }

代码说明:

比较Demo1_2 和 Demo1_1,我们发现,Demo1_2中的MyThread类是直接继承于Thread,而且t1和t2都是MyThread子线程。

幸运的是,在“Demo1_2的run()方法”也调用了synchronized(this),正如“Demo1_1的run()方法”也调用了synchronized(this)一样!

那么,Demo1_2的执行流程是不是和Demo1_1一样呢?

运行结果:

t1 loop 0
t2 loop 0
t1 loop 1
t2 loop 1
t1 loop 2
t2 loop 2
t1 loop 3
t2 loop 3
t1 loop 4
t2 loop 4

结果说明:

如果这个结果一点也不令你感到惊讶,那么我相信你对synchronized和this的认识已经比较深刻了。否则的话,请继续阅读这里的分析。

synchronized(this)中的this是指“当前的类对象”,即synchronized(this)所在的类对应的当前对象。它的作用是获取“当前对象的同步锁”。

对于Demo1_2中,synchronized(this)中的this代表的是MyThread对象,而t1和t2是两个不同的MyThread对象,因此t1和t2在执行synchronized(this)时,获取的是不同对象的同步锁。对于Demo1_1对而言,synchronized(this)中的this代表的是MyRunable对象;t1和t2共同一个MyRunable对象,因此,一个线程获取了对象的同步锁,会造成另外一个线程等待。

第二条

当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程仍然可以访问“该对象”的非同步代码块。

下面是“synchronized代码块”对应的演示程序。

 class Count {
  // 含有synchronized同步块的方法
  public void synMethod() {
   synchronized(this) {
    try {
     for (int i = 0; i < 5; i++) {
     Thread.sleep(100); // 休眠100ms
      System.out.println(Thread.currentThread().getName() + " synMethod loop " + i);
     }
    } catch (InterruptedException ie) {
    }
   }
  }
  // 非同步的方法
  public void nonSynMethod() {
   try {
    for (int i = 0; i < 5; i++) {
     Thread.sleep(100);
     System.out.println(Thread.currentThread().getName() + " nonSynMethod loop " + i);
    }
   } catch (InterruptedException ie) {
   }
  }
 }
 public class Demo {
  public static void main(String[] args) {
   final Count count = new Count();
   // 新建t, t会调用“count对象”的synMethod()方法
   Thread t = new Thread(
     new Runnable() {
      @Override
      public void run() {
       count.synMethod();
      }
    }, "t1");
  // 新建t2, t2会调用“count对象”的nonSynMethod()方法
  Thread t2 = new Thread(
     new Runnable() {
      @Override
      public void run() {
       count.nonSynMethod();
      }
     }, "t2");
  t1.start(); // 启动t1
   t2.start(); // 启动t2
  }
 }

运行结果:

t1 synMethod loop 0
t2 nonSynMethod loop 0
t1 synMethod loop 1
t2 nonSynMethod loop 1
t1 synMethod loop 2
t2 nonSynMethod loop 2
t1 synMethod loop 3
t2 nonSynMethod loop 3
t1 synMethod loop 4
t2 nonSynMethod loop 4

结果说明:

主线程中新建了两个子线程t1和t2。t1会调用count对象的synMethod()方法,该方法内含有同步块;而t2则会调用count对象的nonSynMethod()方法,该方法不是同步方法。t1运行时,虽然调用synchronized(this)获取“count的同步锁”;但是并没有造成t2的阻塞,因为t2没有用到“count”同步锁。

第三条

当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的其他的“synchronized方法”或者“synchronized代码块”的访问将被阻塞。

我们将上面的例子中的nonSynMethod()方法体的也用synchronized(this)修饰。修改后的源码如下:

 class Count {
  // 含有synchronized同步块的方法
  public void synMethod() {
   synchronized(this) {
    try {
     for (int i = 0; i < 5; i++) {
      Thread.sleep(); // 休眠ms
      System.out.println(Thread.currentThread().getName() + " synMethod loop " + i);
     }
    } catch (InterruptedException ie) {
    }
   }
  }
  // 也包含synchronized同步块的方法
  public void nonSynMethod() {
   synchronized(this) {
    try {
    for (int i = 0; i < 5; i++) {
      Thread.sleep(100);
      System.out.println(Thread.currentThread().getName() + " nonSynMethod loop " + i);
     }
    } catch (InterruptedException ie) {
    }
   }
  }
 }
 public class Demo3 {
  public static void main(String[] args) {
   final Count count = new Count();
   // 新建t1, t1会调用“count对象”的synMethod()方法
  Thread t1 = new Thread(
     new Runnable() {
      @Override
      public void run() {
       count.synMethod();
      }
    }, "t1");
  // 新建t2, t2会调用“count对象”的nonSynMethod()方法
   Thread t2 = new Thread(
     new Runnable() {
      @Override
      public void run() {
       count.nonSynMethod();
      }
     }, "t2");
  t1.start(); // 启动t1
  t2.start(); // 启动t2
  }
 }

运行结果:

t1 synMethod loop 0
t1 synMethod loop 1
t1 synMethod loop 2
t1 synMethod loop 3
t1 synMethod loop 4
t2 nonSynMethod loop 0
t2 nonSynMethod loop 1
t2 nonSynMethod loop 2
t2 nonSynMethod loop 3
t2 nonSynMethod loop 4

结果说明:

主线程中新建了两个子线程t1和t2。t1和t2运行时都调用synchronized(this),这个this是Count对象(count),而t1和t2共用count。因此,在t1运行时,t2会被阻塞,等待t1运行释放“count对象的同步锁”,t2才能运行。

synchronized方法 和 synchronized代码块

“synchronized方法”是用synchronized修饰方法,而 “synchronized代码块”则是用synchronized修饰代码块。

synchronized方法示例

public synchronized void foo1() {
 System.out.println("synchronized methoed");
}

synchronized代码块

public void foo2() {
 synchronized (this) {
  System.out.println("synchronized methoed");
 }
}

synchronized代码块中的this是指当前对象。也可以将this替换成其他对象,例如将this替换成obj,则foo2()在执行synchronized(obj)时就获取的是obj的同步锁。

synchronized代码块可以更精确的控制冲突限制访问区域,有时候表现更高效率。下面通过一个示例来演示:

// Demo4.java的源码
 public class Demo4 {
  public synchronized void synMethod() {
  for(int i=0; i<1000000; i++)
    ;
  }
  public void synBlock() {
   synchronized( this ) {
    for(int i=0; i<1000000; i++)
     ;
   }
  }
  public static void main(String[] args) {
   Demo4 demo = new Demo4();
   long start, diff;
   start = System.currentTimeMillis();    // 获取当前时间(millis)
   demo.synMethod();        // 调用“synchronized方法”
   diff = System.currentTimeMillis() - start;  // 获取“时间差值”
   System.out.println("synMethod() : "+ diff);
   start = System.currentTimeMillis();    // 获取当前时间(millis)
   demo.synBlock();        // 调用“synchronized方法块”
   diff = System.currentTimeMillis() - start;  // 获取“时间差值”
   System.out.println("synBlock() : "+ diff);
  }
 }

(某一次)执行结果:

synMethod() : 11
synBlock() : 3

实例锁 和 全局锁

实例锁 -- 锁在某一个实例对象上。如果该类是单例,那么该锁也具有全局锁的概念。

实例锁对应的就是synchronized关键字。

全局锁 -- 该锁针对的是类,无论实例多少个对象,那么线程都共享该锁。

全局锁对应的就是static synchronized(或者是锁在该类的class或者classloader对象上)。

关于“实例锁”和“全局锁”有一个很形象的例子:

pulbic class Something {
 public synchronized void isSyncA(){}
 public synchronized void isSyncB(){}
 public static synchronized void cSyncA(){}
 public static synchronized void cSyncB(){}
}

假设,Something有两个实例x和y。分析下面4组表达式获取的锁的情况。

(01) x.isSyncA()与x.isSyncB()
(02) x.isSyncA()与y.isSyncA()
(03) x.cSyncA()与y.cSyncB()
(04) x.isSyncA()与Something.cSyncA()

(01) 不能被同时访问。因为isSyncA()和isSyncB()都是访问同一个对象(对象x)的同步锁!

 // LockTest1.java的源码
 class Something {
  public synchronized void isSyncA(){
   try {
    for (int i = 0; i < 5; i++) {
     Thread.sleep(); // 休眠ms
     System.out.println(Thread.currentThread().getName()+" : isSyncA");
    }
   }catch (InterruptedException ie) {
   }
  }
  public synchronized void isSyncB(){
   try {
   for (int i = 0; i < 5; i++) {
     Thread.sleep(100); // 休眠100ms
     System.out.println(Thread.currentThread().getName()+" : isSyncB");
    }
   }catch (InterruptedException ie) {
   }
  }
 }
 public class LockTest {
  Something x = new Something();
  Something y = new Something();
  // 比较(01) x.isSyncA()与x.isSyncB()
  private void test1() {
  // 新建t11, t11会调用 x.isSyncA()
   Thread t11 = new Thread(
     new Runnable() {
      @Override
      public void run() {
       x.isSyncA();
      }
    }, "t11");
   // 新建t12, t12会调用 x.isSyncB()
  Thread t12 = new Thread(
    new Runnable() {
     @Override
     public void run() {
       x.isSyncB();
      }
    }, "t12");
  t11.start(); // 启动t11
   t12.start(); // 启动t12
 }
  public static void main(String[] args) {
  LockTest1 demo = new LockTest1();
  demo.test1();
  }
 }

运行结果:
 
t11 : isSyncA
t11 : isSyncA
t11 : isSyncA
t11 : isSyncA
t11 : isSyncA
t12 : isSyncB
t12 : isSyncB
t12 : isSyncB
t12 : isSyncB
t12 : isSyncB

(02) 可以同时被访问。因为访问的不是同一个对象的同步锁,x.isSyncA()访问的是x的同步锁,而y.isSyncA()访问的是y的同步锁。

// LockTest2.java的源码
 class Something {
   public synchronized void isSyncA(){
     try {
      for (int i = 0; i < 5; i++) {
         Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : isSyncA");
       }
     }catch (InterruptedException ie) {
     }
   }
   public synchronized void isSyncB(){
     try {
       for (int i = 0; i < 5; i++) {
        Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : isSyncB");
       }
     }catch (InterruptedException ie) {
     }
   }
   public static synchronized void cSyncA(){
     try {
      for (int i = 0; i < 5; i++) {
        Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : cSyncA");
       }
     }catch (InterruptedException ie) {
     }
   }
   public static synchronized void cSyncB(){
     try {
      for (int i = 0; i < 5; i++) {
        Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : cSyncB");
       }
     }catch (InterruptedException ie) {
     }
   }
 }
 public class LockTest2 {
   Something x = new Something();
   Something y = new Something();
  // 比较(02) x.isSyncA()与y.isSyncA()
  private void test2() {
     // 新建t21, t21会调用 x.isSyncA()
    Thread t21 = new Thread(
        new Runnable() {
           @Override
          public void run() {
           x.isSyncA();
          }
       }, "t21");
    // 新建t22, t22会调用 x.isSyncB()
    Thread t22 = new Thread(
        new Runnable() {
          @Override
          public void run() {
             y.isSyncA();
          }
        }, "t22");
    t21.start(); // 启动t21
     t22.start(); // 启动t22
  }
   public static void main(String[] args) {
     LockTest2 demo = new LockTest2();
     demo.test2();
   }
 }

运行结果:

t21 : isSyncA
t22 : isSyncA
t21 : isSyncA
t22 : isSyncA
t21 : isSyncA
t22 : isSyncA
t21 : isSyncA
t22 : isSyncA
t21 : isSyncA
t22 : isSyncA

(03) 不能被同时访问。因为cSyncA()和cSyncB()都是static类型,x.cSyncA()相当于Something.isSyncA(),y.cSyncB()相当于Something.isSyncB(),因此它们共用一个同步锁,不能被同时反问。

 // LockTest3.java的源码
 class Something {
   public synchronized void isSyncA(){
     try {
      for (int i = 0; i < 5; i++) {
         Thread.sleep(); // 休眠ms
         System.out.println(Thread.currentThread().getName()+" : isSyncA");
       }
     }catch (InterruptedException ie) {
     }
   }
   public synchronized void isSyncB(){
     try {
       for (int i = 0; i < 5; i++) {
        Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : isSyncB");
       }
     }catch (InterruptedException ie) {
     }
   }
   public static synchronized void cSyncA(){
     try {
       for (int i = 0; i < 5; i++) {
       Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : cSyncA");
       }
     }catch (InterruptedException ie) {
     }
   }
   public static synchronized void cSyncB(){
     try {
       for (int i = 0; i < 5; i++) {
        Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : cSyncB");
       }
     }catch (InterruptedException ie) {
     }
   }
 }
 public class LockTest3 {
   Something x = new Something();
   Something y = new Something();
  // 比较(03) x.cSyncA()与y.cSyncB()
   private void test3() {
     // 新建t31, t31会调用 x.isSyncA()
     Thread t31 = new Thread(
         new Runnable() {
           @Override
           public void run() {
             x.cSyncA();
           }
         }, "t31");
    // 新建t32, t32会调用 x.isSyncB()
    Thread t32 = new Thread(
         new Runnable() {
           @Override
           public void run() {
             y.cSyncB();
           }
        }, "t32");
    t31.start(); // 启动t31
     t32.start(); // 启动t32
  }
   public static void main(String[] args) {
    LockTest3 demo = new LockTest3();
    demo.test3();
   }
 }

运行结果:

t31 : cSyncA
t31 : cSyncA
t31 : cSyncA
t31 : cSyncA
t31 : cSyncA
t32 : cSyncB
t32 : cSyncB
t32 : cSyncB
t32 : cSyncB
t32 : cSyncB

(04) 可以被同时访问。因为isSyncA()是实例方法,x.isSyncA()使用的是对象x的锁;而cSyncA()是静态方法,Something.cSyncA()可以理解对使用的是“类的锁”。因此,它们是可以被同时访问的。

// LockTest4.java的源码
 class Something {
   public synchronized void isSyncA(){
     try {
       for (int i = 0; i < 5; i++) {
         Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : isSyncA");
       }
     }catch (InterruptedException ie) {
     }
   }
   public synchronized void isSyncB(){
     try {
       for (int i = 0; i < 5; i++) {
        Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : isSyncB");
       }
     }catch (InterruptedException ie) {
     }
   }
   public static synchronized void cSyncA(){
     try {
      for (int i = 0; i < 5; i++) {
        Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : cSyncA");
       }
     }catch (InterruptedException ie) {
     }
   }
   public static synchronized void cSyncB(){
     try {
       for (int i = 0; i < 5; i++) {
        Thread.sleep(100); // 休眠100ms
         System.out.println(Thread.currentThread().getName()+" : cSyncB");
       }
     }catch (InterruptedException ie) {
     }
   }
 }
 public class LockTest {
   Something x = new Something();
   Something y = new Something();
  // 比较(04) x.isSyncA()与Something.cSyncA()
  private void test4() {
     // 新建t41, t41会调用 x.isSyncA()
     Thread t = new Thread(
         new Runnable() {
           @Override
           public void run() {
             x.isSyncA();
           }
        }, "t41");
     // 新建t42, t42会调用 x.isSyncB()
    Thread t42 = new Thread(
         new Runnable() {
           @Override
          public void run() {
            Something.cSyncA();
          }
         }, "t42");
    t41.start(); // 启动t41
   t42.start(); // 启动t42
  }
  public static void main(String[] args) {
    LockTest4 demo = new LockTest4();
    demo.test4();
  }
 }

运行结果:

t41 : isSyncA
t42 : cSyncA
t41 : isSyncA
t42 : cSyncA
t41 : isSyncA
t42 : cSyncA
t41 : isSyncA
t42 : cSyncA
t41 : isSyncA
t42 : cSyncA

以上所述是小编给大家介绍的Java synchronized关键,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 深入理解java中的synchronized关键字

    synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A,没有的话,直接运行它包括两种用法:synchronized 方法和 synchronized 块. 1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法.如: 复制代码 代码如下: publ

  • java多线程编程之使用Synchronized关键字同步类方法

    复制代码 代码如下: public synchronized void run(){     } 从上面的代码可以看出,只要在void和public之间加上synchronized关键字,就可以使run方法同步,也就是说,对于同一个Java类的对象实例,run方法同时只能被一个线程调用,并当前的run执行完后,才能被其他的线程调用.即使当前线程执行到了run方法中的yield方法,也只是暂停了一下.由于其他线程无法执行run方法,因此,最终还是会由当前的线程来继续执行.先看看下面的代码:sych

  • 深入Synchronized和java.util.concurrent.locks.Lock的区别详解

    主要相同点:Lock能完成Synchronized所实现的所有功能.主要不同点:Lock有比Synchronized更精确的线程予以和更好的性能.Synchronized会自动释放锁,但是Lock一定要求程序员手工释放,并且必须在finally从句中释放.synchronized 修饰方法时 表示同一个对象在不同的线程中 表现为同步队列如果实例化不同的对象 那么synchronized就不会出现同步效果了.1.对象的锁 所有对象都自动含有单一的锁. JVM负责跟踪对象被加锁的次数.如果一个对象被

  • Java 多线程同步 锁机制与synchronized深入解析

    打个比方:一个object就像一个大房子,大门永远打开.房子里有很多房间(也就是方法).这些房间有上锁的(synchronized方法), 和不上锁之分(普通方法).房门口放着一把钥匙(key),这把钥匙可以打开所有上锁的房间.另外我把所有想调用该对象方法的线程比喻成想进入这房子某个 房间的人.所有的东西就这么多了,下面我们看看这些东西之间如何作用的. 在此我们先来明确一下我们的前提条件.该对象至少有一个synchronized方法,否则这个key还有啥意义.当然也就不会有我们的这个主题了. 一

  • Java 中 synchronized的用法详解(四种用法)

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入. 例如: public synchronized void synMethod() { //方法体 }

  • java多线程编程之使用Synchronized块同步变量

    下面的代码演示了如何同步特定的类方法: 复制代码 代码如下: package mythread; public class SyncThread extends Thread{ private static String sync = ""; private String methodType = ""; private static void method(String s) {  synchronized (sync)  {sync = s;System.out

  • Java synchronized关键_动力节点Java学院整理

    synchronized原理 在java中,每一个对象有且仅有一个同步锁.这也意味着,同步锁是依赖于对象而存在. 当我们调用某对象的synchronized方法时,就获取了该对象的同步锁.例如,synchronized(obj)就获取了"obj这个对象"的同步锁. 不同线程对同步锁的访问是互斥的.也就是说,某时间点,对象的同步锁只能被一个线程获取到!通过同步锁,我们就能在多线程中,实现对"对象/方法"的互斥访问. 例如,现在有两个线程A和线程B,它们都会访问&quo

  • Java线程让步_动力节点Java学院整理

    yield()介绍 yield()的作用是让步.它能让当前线程由"运行状态"进入到"就绪状态",从而让其它具有相同优先级的等待线程获取执行权:但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权:也有可能是当前线程又进入到"运行状态"继续运行! yield()示例 下面,通过示例查看它的用法. // YieldTest.java的源码 class ThreadA extends Thread{ public

  • Java线程休眠_动力节点Java学院整理

    sleep()介绍 sleep() 定义在Thread.java中. sleep() 的作用是让当前线程休眠,即当前线程会从"运行状态"进入到"休眠(阻塞)状态".sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间:在线程重新被唤醒时,它会由"阻塞状态"变成"就绪状态",从而等待cpu的调度执行. sleep()示例 下面通过一个简单示例演示sleep()的用法. // SleepTest.java的源码 cl

  • Java Set简介_动力节点Java学院整理

    1. 概述   Java 中的Set和正好和数学上直观的集(set)的概念是相同的.Set最大的特性就是不允许在其中存放的元素是重复的.根据这个特点,我们就可以使用Set 这个接口来实现前面提到的关于商品种类的存储需求.Set 可以被用来过滤在其他集合中存放的元素,从而得到一个没有包含重复新的集合. 2. 常用方法 按照定义,Set 接口继承 Collection 接口,而且它不允许集合中存在重复项.所有原始方法都是现成的,没有引入新方法.具体的 Set 实现类依赖添加的对象的 equals()

  • 十大常见Java String问题_动力节点Java学院整理

    本文介绍Java中关于String最常见的10个问题: 1. 字符串比较,使用 "==" 还是 equals() ? 简单来说, "==" 判断两个引用的是不是同一个内存地址(同一个物理对象). 而 equals 判断两个字符串的值是否相等. 除非你想判断两个string引用是否同一个对象,否则应该总是使用 equals()方法. 如果你了解 字符串的驻留 ( String Interning ) 则会更好地理解这个问题 2. 对于敏感信息,为何使用char[]要比

  • Java数组优点和缺点_动力节点Java学院整理

    数组是Java语言的基本知识之一,在深入学习Java基础后,我们都知道那些容器,在之后,在我们学习.工作的过程中基本就是使用容器了,很少很使用数组,那么为什么还要有数组呢,我也是今天才遇到这个问题,专门的找资料学习了一下. 数组与其他种类的容器之间的区别有三方面:效率.类型和保存基本类型的能力,当然现在有泛型,保存类型的区别已经不大了. 数组较容器,最大的优点就是效率.在Java中,数组是一种效率最高的存储和随机访问对象引用序列的方式,数组就是一个简单的线性序列,这使得元素访问非常快速,无论使用

  • Java Map简介_动力节点Java学院整理

    Map简介 将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值.此接口取代 Dictionary 类,后者完全是一个抽象类,而不是一个接口. Map 接口提供三种collection 视图,允许以键集.值集或键-值映射关系集的形式查看某个映射的内容.映射顺序 定义为迭代器在映射的 collection 视图上返回其元素的顺序.某些映射实现可明确保证其顺序,如 TreeMap 类:另一些映射实现则不保证顺序,如HashMap 类. 注:将可变对象用作映射键时必须格外小心.当对

  • Java Iterator迭代器_动力节点Java学院整理

    迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的.只要拿到这个对象,使用迭代器就可以遍历这个对象的内部. 1.Iterator Java提供一个专门的迭代器<<interface>>Iterator,我们可以对某个序列实现该interface,来提供标准的Java迭代器.Iterator接口实现后的功能是"使用"一个迭代器. 文档定义: Package java.util; publici

  • Java二分法查找_动力节点Java学院整理

    算法 假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量front,mid,end分别指向数据的上界,中间和下界,mid=(front+end)/2. 开始令front=0(指向3),end=7(指向88),则mid=3(指向36).因为mid>x,故应在前半段中查找. 令新的end=mid-1=2,而front=0不变,则新的mid=1.此时x>mid,故确定应在后半段中查找. 令新的front=mid+1=2,而end=2不变,则新的mid=2,此时a

  • Java方法重写_动力节点Java学院整理

    一.方法重写(Override) 在Java中如何来定义重写:Java程序中类的继承特性可以产生一个子类,子类继承父类就拥有了父类的非私有的属性(方法和变量),在子类中可以增加自己的属性(方法和变量),同时也可以对父类中的方法进行扩展,以增强自己的功能,这样就称之为重写,也称为复写或者覆盖.所谓方法重写就是子类的方法和父类中继承下来的方法具有完全相同的方法名.返回值类型.方法的参数个数以及参数类型,这样才能被称为方法重写. 代码体现: // 这是父类的定义 public class Person

随机推荐