笔者在学到多线程的Thread和Runnable时因误将接口写成继承了Thread类,但之后程序正常执行,并与使用Runnable接口结果一致。由此对于学过的Tread不能共享资源这一知识产生了疑问,经查阅找到了彻底理解Runnable和Thread的区别_zhaojianting的博客-CSDN博客_runnable这位前辈的文章,在和同学讨论后,发现前辈的写法有些不够严谨,这里贴上相应的写法,用一个例子来说明:一家人共用一张银行卡,父母往银行卡里存钱,儿女从银行卡里取钱。
//这里是银行卡,有存取两种方法
public class BankCard {
private double money;
public BankCard() {
}
public BankCard(double money) {
this.money = money;
}
public void setMoney(double money) {
this.money = money;
}
public synchronized void save(double money) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.money += money;
System.out.println(Thread.currentThread().getName() + "存了" + money + "元,余
额:" + this.money);
}
public synchronized void take(double money) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.money -= money;
System.out.println(Thread.currentThread().getName() + "取了" + money + "元,余
额:" + this.money);
}
}
存钱取钱各执行指定次数,每次金额为1000,为了使结果更直观,在存钱取钱代码中加了sleep休眠;
//这是存钱代码
public class AddMoney extends Thread{
BankCard card ;
public AddMoney(BankCard card) {
this.card = card;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
card.save(1000);
}
}
}
//这是取钱代码
public class SubMoney extends Thread {
BankCard card ;
public SubMoney(BankCard card) {
this.card = card;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
card.take(1000);
}
}
}
在上述代码中,通过将addMoney和subMoney放入thread线程来实现共享银行卡。
//这是测试类
public class Test {
public static void main(String[] args) {
BankCard card = new BankCard();
AddMoney addMoney = new AddMoney(card);
SubMoney subMoney = new SubMoney(card);
Thread thread1 = new Thread(addMoney, "父亲");
Thread thread2 = new Thread(addMoney, "母亲");
Thread thread3 = new Thread(subMoney, "儿子");
Thread thread4 = new Thread(subMoney, "女儿");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
下图是执行结果:
虽然实现了资源共享,但是在测试类中的代码本质上是将线程放入到线程中去执行,这种写法显得有些多余,于是笔者将代码进行了修改得出了下面的代码,
BankCard不变,修改其他三个类:
//AddMoney的构造方法
public AddMoney(String name, BankCard card) {
super(name);
this.card = card;
}
//SubMoney的构造方法
public SubMoney(String name, BankCard card) {
super(name);
this.card = card;
}
SubMoney和AddMoney两个类各添加带参构造方法;
测试类:
public class Test {
public static void main(String[] args) {
BankCard card = new BankCard();
AddMoney addMoney = new AddMoney("父亲",card);
AddMoney addMoney1 = new AddMoney("母亲",card);
SubMoney subMoney = new SubMoney("儿子",card);
SubMoney subMoney1 = new SubMoney("女儿",card);
addMoney.start();
addMoney1.start();
subMoney.start();
subMoney1.start();
}
}
如上代码,即可实现直接将线程执行而不需要再带入到另一个线程里;
由此我得出了Thread也可实现资源共享的结论,但如果考虑前面引用的文章里的例子,如果不用一个共同的线程来执行其他线程,就没办法在没有其他类似于BandCard类的情况下实现资源共享了,即使实现了,也是多余的写法(线程套线程),由此,我觉得Thread不能实现资源共享这句话可能是有些片面,但也不能说完全不对,因为在一般情况下,需要资源共享使用Runnable更合适,而且我在网上看到有经验的人也说工作中不会用Thread实现共享的。