今天学习了的主要内容:
1.多线程访问同一个共享的数据情况解析
2.java内存模型JMM
3.创建多线程调用一个变量的情况
多线程访问同一个共享的数据情况解析:
静态域、数组还有实例都在堆中被创建,都能够被任何线程访问。
可能会被多个线程并发访问然后被修改,这种情况没有任何警告。
java内存模型JMM:
它主要描述了程序中的变量在啥时候以啥方式和顺序以及怎么存储
到主内存中,以及以什么样的方式从主内存中读取出来。
java程序当中线程总共有两种内存使用类型:
工作内存(working memory)和主内存(main memory)。
主内存就是所有线程共享的内存区域,可以用于线程之间互相通信。
每个线程都有属于自己的用于存储使用的局部变量的栈,都有自己的工作内存。
原子性(atomicity):除了long和double外,对象属性的读写是原子的。
可见性(visibility):一个线程怎样读取另一个线程工作空间修改过的值
当某个线程首次读取主空间变量的值时,它有可能是初始值也可能是其他线程写入后 的值。
volatile(不稳定的)变量总是写入主内存中,也总是从主内存中读取变量的值。
当线程终止时该线程从主空间得到的在工作空间操作的值将被写入主内存。
线程进入同步块时工作空间中的值将被读取。
有序性(ordering):线程中执行的操作都是有序的。
创建多线程调用一个变量的情况
代码:
Bank类(模拟银行的账户提供提款功能):
package LessonForThread05;
public class Bank
{
protected int money = 1000;
public int getMoney()
{
return money;
}
public void setMoney(int money)
{
this.money = money;
}
public void drawMoney(int sum)
{
if (sum <= 0)
{
System.out.println("您输入的数值不正确!");
return;
}else if (sum > this.getMoney())
{
System.out.println("您输入的金额超出自身账户余额了!");
return;
}else
{
try
{
Thread.sleep(2000);//在执行取款前,先让他休息一秒,使线程交叉取款
} catch (InterruptedException e)
{
e.printStackTrace();
}
this.setMoney((this.getMoney() - sum));
System.out.println("本次取款:"+sum+"元,账户余额为:"+this.getMoney());
}
}
}
Person类(个人提款动作线程实现体):
package LessonForThread05;
public class Person implements Runnable
{
protected Bank account;
public Person(Bank account)
{
this.account = account;
}
@Override
public void run()
{
this.account.drawMoney(300);
}
}
Test类(实现多线程调用同一个属性):
package LessonForThread05;
public class Test
{
public static void main(String[] args)
{
Bank b1 = new Bank();
for (int i=0; i<10; i++)//反复创建十个不同的线程来调用取钱方法。
{
Thread t = new Thread(new Person(b1));
t.start();
}
try //主线程让出时间来给子线程取钱
{
Thread.sleep(10000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("完毕!目前余额:"+b1.getMoney());
}
}
本篇部分文字来源于:
咕嘟咖啡杨海滨老师 — 《java编程语言高级特性》
在这里十分感谢老师能够给我带来学习的激情。
2020.10.23
可以转载我的学习日记但请注明出处,谢谢。
本文章是本人学习笔记,不进行任何商用!也请别拿去商用!只为记录本人学习历程。
毕