首页 > 图灵资讯 > 技术篇>正文

多线程之共享数据

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学习之路平步青云!

上一篇 捍卫java开发安全的十三条铁则
下一篇 10道互联网公司java面试题(附答案)

文章素材均来源于网络,如有侵权,请联系管理员删除。