Java 多个线程之间共享数据
线程执行的代码相同
如果每个线程执行的代码相同,可以使用同一个Runnable对象,在这个Runnable对象中定义共享数据即可,例如,卖票系统就可以这么做。
public class SellTicket {
//卖票系统,多个窗口的处理逻辑是相同的
public static void main(String[] args) {
Ticket t = new Ticket();
new Thread(t).start();
new Thread(t).start();
}}
/**
* 将属性和处理逻辑封装在同一个类中
*
* @author Wiener
*/
class Ticket implements Runnable {
// 资源初始值
private int ticket = 10;
public synchronized void run() {
while (ticket > 0) {
ticket--;
System.out.println("当前票数为:" + ticket);
}
}}
每个线程执行的代码不同
如果每个线程执行的代码不同,这时候需要用不同的Runnable对象。例如,银行存取款系统中设计2个线程,一个线程对j增加1,另外一个线程对j减1。
将共享数据抽象到一个类中,并将对这个数据的操作作为这个类的方法,这么设计可以轻而易举地做到同步,只要在方法上加synchronized关键字即可。
package com.hoss.ext.authentication;
/**
* 两个线程执行的方法不一样
*
* @author Wiener
* @date 2021/4/25
*/
public class MultiThreadShareData {
// 库存10
private int j = 10;
public static void main(String[] args) {
MultiThreadShareData multiThreadShareData = new MultiThreadShareData();
for (int i = 0; i < 2; i++) {
//增加
new Thread(multiThreadShareData.new ShareData1()).start();
//减少
new Thread(multiThreadShareData.new ShareData2()).start();
}
}
//自增
private synchronized void Inc() {
j++;
System.out.println(Thread.currentThread().getName() + " inc " + j);
}
//自减
private synchronized void Dec() {
j--;
System.out.println(Thread.currentThread().getName() + " dec " + j);
}
class ShareData1 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
Inc();
}
}
}
class ShareData2 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
Dec();
}
}
}
}
执行结果如下:
Thread-1 dec 9
Thread-1 dec 8
Thread-1 dec 7
Thread-1 dec 6
Thread-1 dec 5
Thread-3 dec 4
Thread-3 dec 3
Thread-3 dec 2
Thread-3 dec 1
Thread-3 dec 0
Thread-2 inc 1
Thread-2 inc 2
Thread-2 inc 3
Thread-2 inc 4
Thread-2 inc 5
Thread-0 inc 6
Thread-0 inc 7
Thread-0 inc 8
Thread-0 inc 9
Thread-0 inc 10
关键还是思想:将共享数据和业务处理逻辑封装在一个类中,业务逻辑线程对象(即加1的线程和减1的线程操作)在执行时,直接调用该类中的处理逻辑。这样做,更符合面向对象,更易于维护。
总结一下,对于多线程间共享变量的操作,需要实现互斥,使得对该共享变量的操作实现原子性。
Reference
读后有收获,小礼物走一走,请作者喝咖啡。
Buy me a coffee. ☕Get red packets.
作者:楼兰胡杨
本文版权归作者和博客园共有,欢迎转载,但请注明原文链接,并保留此段声明,否则保留追究法律责任的权利。