多线程之共享数据
2023-04-03 15:04:09
当一个数据被多个线程读取时,通过检查数据的值来判断和执行后的操作是极其不安全的。因为在判断之后,数据的值可能已经被其他线程修改,判断条件可能不确定,但在判断之后,以后的操作“将错就错”地继续进行。需要在这个时候使用多线程之共享数据。
多线程的共享数据它是多线程多机制中数据处理不可或缺的功能,能有效防止数据在多线程中的数据混淆。在 Java 在传统的线程机制中,共享数据的方式大致可以分为两种。
- 多个线程行为一致,共同操作一个数据源:也就是说,每个线程执行相同的代码可以使用相同的代码 Runnable 对象,这个 Runnable 对象中有共享数据,比如最经典、最有说服力的售票系统。
如果多个线程执行的代码相同,则可以使用相同的代码Runnable,Runable包含共享数据对象:
public class ThreadTestttttttt1 {
public static void main(String[] args) {
ShareData shareData = new ShareData();//共享数据对象
for (int i = 0; i < 4; i++) {
new Thread(new RunnableCusToInc(shareData), "Thread " + i).start();
}
}
}
/**
* 共享数据类
**/
class ShareData {
private int num = 10;
public synchronized void inc() {
num++;
System.out.println(Thread.currentThread().getName()
+ ": invoke inc method num =" + num);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
*多线程类
**/
class RunnableCusToInc implements Runnable {
private ShareData shareData;//共享数据对象
public RunnableCusToInc(ShareData data) {
this.shareData = data;
}
}
}
}
/**
* 共享数据类
**/
class ShareData2 {
private int num = 10;
public synchronized void inc() {
num++;
System.out.println(Thread.currentThread().getName()
+ ": invoke inc method num =" + num);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 多线程类
**/
}
}
(2).将这些 Runnable 作为某一类的内部类,共享数据作为外部类的成员变量,每个线程的共享数据操作方法也分配给外部类,以实现共享数据的相互排斥和通信,作为内部类的每个Runnable 对象调用这些外部方法。
public class ThreadTest3 {
public static void main(String[] args) {
// 公共数据
final ShareData shareData = new ShareData();
for (int i = 0; i < 4; i++) {
if (i % 2 == 0) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
shareData.inc();
}
}
}, "Thread " + i).start();
} else {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
shareData.dec();
}
}
}, "Thread " + i).start();
}
}
}
class ShareData {
private int num = 10;
public synchronized void inc() {
num++;
System.out.println(Thread.currentThread().getName()
+ ": invoke inc method num =" + num);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void dec() {
num--;
System.err.println(Thread.currentThread().getName()
+ ": invoke dec method num =" + num);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
通过以上例子,不难发现多线程实际上是多线程的共享数据最重要的是相互排斥。多线程共享一个变量,可以实现变量操作的原子性。想学习java多线程更多知识,欢迎观看本网站的多线程专业视频课程,帮助您java学习之路平步青云!