Java 简明教程
Java - Block Synchronization
当我们在 Java 程序内启动 two or more threads时,可能会出现多个线程尝试访问同一资源的情况,最终它们可能会由于并发问题而产生意外结果。例如,如果多个线程尝试在同一文件中写入,则它们可能会破坏数据,因为其中一个线程可以覆盖数据,或者在其中一个线程打开同一文件的同时,另一个线程可能关闭同一文件。
因此,需要同步多个线程的操作并确保在给定的时间点只有单个线程可以访问资源。这是使用监视器的概念来实现的。Java 中的每个对象都与一个监视器相关联,该监视器可以由线程锁定或解锁。一次只能有一个线程对监视器持有锁。
Block Synchronization in Java
Java 编程语言提供了一种非常方便的方法来创建线程并 synchronizing使用同步块来完成它们的任务。您保留此块内的共享资源。
Multithreading Example without Synchronization
这是一个简单的示例,它可能并不会按顺序打印 counter 的值,而且每次运行都会基于线程对 CPU 的可用性产生不同的结果。
Example
package com.tutorialspoint;
class PrintDemo {
public void printCount() {
try {
for(int i = 5; i > 0; i--) {
Thread.sleep(50);
System.out.println("Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread interrupted.");
}
}
}
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
PrintDemo printDemo;
ThreadDemo( String name, PrintDemo pd) {
threadName = name;
printDemo = pd;
}
public void run() {
printDemo.printCount();
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
PrintDemo printDemo = new PrintDemo();
ThreadDemo t1 = new ThreadDemo( "Thread - 1 ", printDemo );
ThreadDemo t2 = new ThreadDemo( "Thread - 2 ", printDemo );
t1.start();
t2.start();
// wait for threads to end
try {
t1.join();
t2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}
Multithreading Example with Synchronization at Block level
以下是按顺序打印计数器值的示例,每次运行都会产生相同的结果。我们在一个块上放置了 synchronized 关键字,以便在方法执行期间计数器递增代码现在按对象锁定。我们使用当前对象作为锁,将其作为参数传递给同步块。
Example
package com.tutorialspoint;
class PrintDemo {
public void printCount() {
try {
for(int i = 5; i > 0; i--) {
Thread.sleep(50);
System.out.println("Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread interrupted.");
}
}
}
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
PrintDemo printDemo;
ThreadDemo( String name, PrintDemo pd) {
threadName = name;
printDemo = pd;
}
public void run() {
synchronized(printDemo) {
printDemo.printCount();
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
PrintDemo printDemo = new PrintDemo();
ThreadDemo t1 = new ThreadDemo( "Thread - 1 ", printDemo );
ThreadDemo t2 = new ThreadDemo( "Thread - 2 ", printDemo );
t1.start();
t2.start();
// wait for threads to end
try {
t1.join();
t2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}
Multithreading Example with Synchronization at Method level
这是一个在每次运行时都会按顺序打印 counter 值的示例,而且每次都产生相同的结果。这次,我们在一个方法上放了 synchronized 关键字,因此在方法执行期间,整个方法会按照对象锁定。
Example
package com.tutorialspoint;
class PrintDemo extends Thread {
public void printCount() {
try {
for(int i = 5; i > 0; i--) {
Thread.sleep(50);
System.out.println("Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread " + Thread.currentThread().getName()+" interrupted.");
}
}
public synchronized void run() {
printCount();
System.out.println("Thread " + Thread.currentThread().getName() + " exiting.");
}
}
public class TestThread {
public static void main(String args[]) {
PrintDemo printDemo = new PrintDemo();
Thread t1 = new Thread(printDemo );
Thread t2 = new Thread(printDemo );
t1.start();
t2.start();
// wait for threads to end
try {
t1.join();
t2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}