📜  Java同步-概念

📅  最后修改于: 2020-09-27 01:34:09             🧑  作者: Mango

Java中的同步

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

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

为什么要使用同步

同步主要用于

  • 为了防止线程干扰。
  • 以防止一致性问题。

同步类型

同步有两种类型

  • 流程同步
  • 线程同步

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

线程同步

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

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

互斥

互斥互助有助于防止线程在共享数据时相互干扰。这可以通过Java中的三种方式完成:

  • 通过同步方法
  • 按同步块
  • 通过静态同步

Java锁的概念

同步是围绕称为锁或监视器的内部实体构建的。每个对象都有与之关联的锁。按照约定,需要对对象的字段进行一致访问的线程必须在访问对象之前获取对象的锁,然后在完成对它们的锁定后释放该锁。

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

无需同步即可了解问题

在此示例中,没有同步,因此输出不一致。让我们来看一个例子:

class Table{
void printTable(int n){//method not synchronized
   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();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output: 5
       100
       10
       200
       15
       300
       20
       400
       25
       500
       

Java同步方法

如果将任何方法声明为同步方法,则称为同步方法。

同步方法用于锁定任何共享资源的对象。

当线程调用同步方法时,它将自动获取该对象的锁,并在线程完成其任务时释放该锁。

//example of java synchronized method
class Table{
 synchronized void printTable(int n){//synchronized method
   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();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output: 5
       10
       15
       20
       25
       100
       200
       300
       400
       500
       

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

在此程序中,我们通过匿名类创建了两个线程,因此所需的编码更少。

//Program of synchronized method by using annonymous class
class Table{
 synchronized void printTable(int n){//synchronized method
   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();//only one object

Thread t1=new Thread(){
public void run(){
obj.printTable(5);
}
};
Thread t2=new Thread(){
public void run(){
obj.printTable(100);
}
};

t1.start();
t2.start();
}
}
Output: 5
       10
       15
       20
       25
       100
       200
       300
       400
       500