Java 多线程的同步代码块详解
在Java中,多线程操作的时候,经常会出现多个线程共享同一个资源的情况。当多个线程同时访问共享资源时,会导致数据不一致的问题,这就需要用到同步代码块来解决。
什么是同步代码块?
同步代码块是Java中实现线程安全的一种机制,用来解决多个线程同时访问共享资源的并发问题。同步代码块是指用 synchronized
关键字修饰的一段代码,被修饰的代码称为同步代码块。
synchronized(锁对象) {
//同步代码块
}
在同步代码块中,一次只能有一个线程进入执行,其他线程必须等待当前线程执行完毕后才能进入执行。通过同步代码块的机制来保证了多线程操作共享数据的正确性。
同步代码块的锁对象
同步代码块需要一个锁对象来实现线程之间的互斥。锁对象可以是任意类型的Java对象,但是多个同步代码块必须使用同一个锁对象,才能够实现同步.
//使用一个共享的锁this
synchronized(this) {
// 同步代码块
}
同步方法与同步代码块
Java中除了使用同步代码块实现线程的同步外,还有使用同步方法的方式实现线程的同步。同步方法是指在方法的定义上添加 synchronized
关键字,这个方法在调用的时候就会自动进行加锁。
使用同步方法实现线程同步的时候,锁对象就是该方法所属对象本身。
public synchronized void method() {
//同步方法
}
同步代码块和同步方法都可以实现线程的同步,但是在使用的时候需要注意:
-
同步代码块能够精确的控制锁的范围和锁的时间,可以提升程序的性能;
-
同步方法代码简单,但是锁的范围不能够精确的控制,可能会降低程序的性能。
示例
下面是一个使用同步代码块实现线程同步的示例代码:
public class ThreadDemo {
private int count = 0;
public synchronized void increment() {
count++;
}
public void doWork() throws InterruptedException {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
increment();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
increment();
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Count :" + count);
}
}
这个示例中,我们定义了一个 ThreadDemo
类,这个类中包含一个 increment()
方法,能够对共享变量 count
进行增加操作。
在 doWork()
方法中,我们创建了两个线程 thread1
和 thread2
,分别对共享变量 count
进行增加操作。为了实现线程同步,我们在 increment()
方法上添加了 synchronized
关键字,用来实现多线程之间的互斥访问。
执行 doWork()
方法后,我们输出了共享变量 count
的最终值。由于 increment()
方法使用同步代码块实现了线程同步,所以最终输出的结果是正确的,每次程序执行完后 count
的值都是 20000
。
示例2
下面是一个同步代码块中使用锁对象的示例代码:
public class ThreadDemo {
private int count = 0;
private static Object lock = new Object();
public void increment() {
synchronized(lock) {
count++;
}
}
public void doWork() throws InterruptedException {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
increment();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
increment();
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Count :" + count);
}
}
这个示例中,我们定义了一个共享变量 count
和一个锁对象 lock
。在 increment()
方法中,我们使用了同步代码块和锁对象来实现线程同步。通过使用锁对象,我们将锁的范围的粒度控制的更细,从而提升了程序的性能。
执行 doWork()
方法后,我们输出了共享变量 count
的最终值。由于 increment()
方法使用同步代码块实现了线程同步,并且使用了锁对象来控制锁的范围,所以最终输出的结果是正确的,每次程序执行完后 count
的值都是 20000
。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 多线程的同步代码块详解 - Python技术站