Java中的同步

Java中的同步是控制多个线程对任何共享资源的访问的能力。

Java同步是在我们只想允许一个线程访问共享资源时的更好选择。

为什么使用同步?

同步主要用于以下两个目的:

  1. 防止线程干扰。
  2. 防止一致性问题。

同步的类型

同步有两种类型:

  1. 进程同步
  2. 线程同步

在这里,我们只讨论线程同步。

线程同步

线程同步有两种类型:互斥和线程间通信。

  1. 互斥

    1. 同步方法
    2. 同步块
    3. 静态同步
  2. 合作(Java中的线程间通信)

互斥

互斥有助于在共享数据时防止线程相互干扰。可以通过以下三种方式实现:

  1. 使用同步方法
  2. 使用同步块
  3. 使用静态同步

Java中的锁概念

同步是围绕着一个称为锁或监视器的内部实体构建的。每个对象都有一个关联的锁。按照惯例,一个线程在访问对象的字段之前必须获取对象的锁,并在完成后释放锁。

从Java 5开始,java.util.concurrent.locks包中包含了多个锁实现。

了解没有同步的问题

在这个例子中,没有使用同步,因此输出是不一致的。让我们看一下例子:

TestSynchronization1.java

class Table{  
void printTable(int n){//方法不同步  
   for(int i=1;i<=5;i++){  
     System.out.println(n*i);  
     try{  
      Thread.sleep(400);  
     }catch(Exception e){System.out.println(e);}  
   }  
  
 }  
}  
  
class MyThread1 extends Thread{  
Table t;  
MyThread1(Table t){  
this.t=t;  
}  
public void run(){  
t.printTable(5);  
}  
  
}  
class MyThread2 extends Thread{  
Table t;  
MyThread2(Table t){  
this.t=t;  
}  
public void run(){  
t.printTable(100);  
}  
}  
  
class TestSynchronization1{  
public static void main(String args[]){  
Table obj = new Table();//只有一个对象  
MyThread1 t1=new MyThread1(obj);  
MyThread2 t2=new MyThread2(obj);  
t1.start();  
t2.start();  
}  
}  

输出:

       5
       100
       10
       200
       15
       300
       20
       400
       25
       500

Java同步方法

如果你将任何方法声明为同步方法,它被称为同步方法。

同步方法用于为任何共享资源锁定一个对象。当一个线程调用同步方法时,它自动获取该对象的锁,并在线程完成任务后释放锁。

TestSynchronization2.java

//java 同步方法示例
class Table{  
 synchronized void printTable(int n){//同步方法  
   for(int i=1;i<=5;i++){  
     System.out.println(n*i);  
     try{  
      Thread.sleep(400);  
     }catch(Exception e){System.out.println(e);}  
   }  
  
 }  
}  
  
class MyThread1 extends Thread{  
Table t;  
MyThread1(Table t){  
this.t=t;  
}  
public void run(){  
t.printTable(5);  
}  
  
}  
class MyThread2 extends Thread{  
Table t;  
MyThread2(Table t){  
this.t=t;  
}  
public void run(){  
t.printTable(100);  
}  
}  
  
public class TestSynchronization2{  
public static void main(String args[]){  
Table obj = new Table();//只有一个对象 
MyThread1 t1=new MyThread1(obj);  
MyThread2 t2=new MyThread2(obj);  
t1.start();  
t2.start();  
}  
}  

输出:

      5
       10
       15
       20
       25
       100
       200
       300
       400
       500

使用匿名类来实现同步方法的示例

在这个程序中,我们使用匿名类创建了两个线程,所以需要较少的代码。

TestSynchronization3.java

//通过使用匿名类的同步方法程序
class Table{  
 synchronized void printTable(int n){//同步方法  
   for(int i=1;i<=5;i++){  
     System.out.println(n*i);  
     try{  
      Thread.sleep(400);  
     }catch(Exception e){System.out.println(e);}  
   }  
  
 }  
}  
  
public class TestSynchronization3{  
public static void main(String args[]){  
final Table obj = new Table();//只有一个对象  
  
Thread t1=new Thread(){  
public void run(){  
obj.printTable(5);  
}  
};  
Thread t2=new Thread(){  
public void run(){  
obj.printTable(100);  
}  
};  
  
t1.start();  
t2.start();  
}  
}  

输出:

       5
       10
       15
       20
       25
       100
       200
       300
       400
       500

标签: java, Java面试题, Java下载, java教程, java技术, Java学习, Java学习教程, Java语言, Java开发, Java入门教程, Java进阶教程, Java高级教程, Java笔试题, Java编程思想