java 什么是线程同步_Java线程同步

当在程序中启动两个或多个线程时,可能存在多个线程尝试访问相同资源的情况,并且最终由于并发问题它们可能产生无法预料的结果。例如,如果多个线程尝试在同一个文件中写入,那么它们可能会破坏数据,因为其中一个线程可以覆盖数据,或者当一个线程同时打开同一个文件时,另一个线程可能正在关闭同一个文件。

因此需要同步多个线程的操作,并确保只有一个线程可以在给定的时间点访问资源。它是使用称为监视器的概念实现的。Java中的每个对象都与一个监视器相关联,一个线程可以锁定或解锁。一次只有一个线程可以锁定监视器。

Java编程语言提供了一种非常方便的方法,即使用synchronized块创建线程并同步其任务。在此块中保留共享资源。以下是synchronized声明的一般形式 -

语法

synchronized(objectidentifier) {

// Access shared variables and other shared resources

}

这里,objectidentifier是对一个对象的引用,该对象的锁与synchronized语句所代表的监视器相关联。下面有两个示例,在示例中使用两个不同的线程打印计数器。当线程不同步时,它们打印的计数器值不是按顺序排列的,但是当通过置于synchronized()块内部打印计数器时,它会为两个线程按顺序打印计数器。

1. 没有同步的多线程示例

这是一个简单的例子,可能会或可能不会按顺序打印计数器值,每次运行它时,它会根据线程的CPU可用性产生不同的结果。

示例

class PrintDemo {

public void printCount() {

try {

for(int i = 5; i > 0; i--) {

System.out.println("Counter --- " + i );

}

} catch (Exception e) {

System.out.println("Thread interrupted.");

}

}

}

class ThreadDemo extends Thread {

private Thread t;

private String threadName;

PrintDemo PD;

ThreadDemo( String name, PrintDemo pd) {

threadName = name;

PD = pd;

}

public void run() {

PD.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 PD = new PrintDemo();

ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD );

ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD );

T1.start();

T2.start();

// wait for threads to end

try {

T1.join();

T2.join();

} catch ( Exception e) {

System.out.println("Interrupted");

}

}

}

执行上面示例代码,得到以下结果 -

Starting Thread - 1

Starting Thread - 2

Counter --- 5

Counter --- 4

Counter --- 3

Counter --- 5

Counter --- 2

Counter --- 1

Counter --- 4

Thread Thread - 1 exiting.

Counter --- 3

Counter --- 2

Counter --- 1

Thread Thread - 2 exiting.

2. 具有同步的多线程示例

下面是按顺序打印计数器值的示例,每次运行它时,都会产生相同的结果。

示例

class PrintDemo {

public void printCount() {

try {

for(int i = 5; i > 0; i--) {

System.out.println("Counter --- " + i );

}

} catch (Exception e) {

System.out.println("Thread interrupted.");

}

}

}

class ThreadDemo extends Thread {

private Thread t;

private String threadName;

PrintDemo PD;

ThreadDemo( String name, PrintDemo pd) {

threadName = name;

PD = pd;

}

public void run() {

synchronized(PD) {

PD.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 PD = new PrintDemo();

ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD );

ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD );

T1.start();

T2.start();

// wait for threads to end

try {

T1.join();

T2.join();

} catch ( Exception e) {

System.out.println("Interrupted");

}

}

}

执行上面示例代码,得到以下结果 -

Starting Thread - 1

Starting Thread - 2

Counter --- 5

Counter --- 4

Counter --- 3

Counter --- 2

Counter --- 1

Thread Thread - 1 exiting.

Counter --- 5

Counter --- 4

Counter --- 3

Counter --- 2

Counter --- 1

Thread Thread - 2 exiting.

¥ 我要打赏

纠错/补充

收藏

加QQ群啦,易百教程官方技术学习群

注意:建议每个人选自己的技术方向加群,同一个QQ最多限加 3 个群。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值