Java教程-Java中的同步

Java中的同步
Java中的同步是控制多个线程对任何共享资源的访问的能力。
Java同步是在我们只想允许一个线程访问共享资源时的更好选择。
为什么使用同步?
同步主要用于以下两个目的:
- 防止线程干扰。
- 防止一致性问题。
同步的类型
同步有两种类型:
- 进程同步
- 线程同步
在这里,我们只讨论线程同步。
线程同步
线程同步有两种类型:互斥和线程间通信。
互斥
- 同步方法
- 同步块
- 静态同步
- 合作(Java中的线程间通信)
互斥
互斥有助于在共享数据时防止线程相互干扰。可以通过以下三种方式实现:
- 使用同步方法
- 使用同步块
- 使用静态同步
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