Java支持多个线程同时访问一个对象或者对象的成员变量,
使用关键字synchronized可以保证了线程对共享变量访问的可见性和排他性
使用cas机制可以控制线程对共享变量写操作的原子性。
一,使用共享对象和synchronized实现数据共享
public static void main(String[] args) {
// 共享的对象
MyData myData = new MyData();
// 创建5个线程 传入共享的对象
for(int i = 0;i<5;i++) {
new MyThread(myData).start();
}
SleepTools.second(5);
System.out.println("main is ended!最终的值"+myData.getJ());
}
//具体操作线程 实现共享对的值+1
private static class MyThread extends Thread{
public MyData myData;
public MyThread(MyData myData) {
this.myData = myData;
}
@Override
public void run() {
try {
//模拟其他业务操作 休眠一秒代替
TimeUnit.SECONDS.sleep(1);
//对共享的数据 +1 操作
synchronized (myData){
addNumber();//值加一操作
}
//模拟其他业务操作 休眠一秒代替
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void addNumber(){
System.out.println(Thread.currentThread().getName()+"取值为 ......."+myData.getJ());
myData.setJ(myData.getJ()+1);
System.out.println(Thread.currentThread().getName()+"增加一后值......."+myData.getJ());
}
}
// 共享的对象类
public static class MyData {
// 共享对象的属性
private int j = 0;
public int getJ() {
return j;
}
public void setJ(int j) {
this.j = j;
}
}
运行结果如下:
Thread-3取值为 .......0
Thread-3增加一后值.......1
Thread-0取值为 .......1
Thread-0增加一后值.......2
Thread-1取值为 .......2
Thread-1增加一后值.......3
Thread-2取值为 .......3
Thread-2增加一后值.......4
Thread-4取值为 .......4
Thread-4增加一后值.......5
main is ended!最终的值5
二,使用静态变量和CAS机制实现,本例直接使用原子操作AtomicInteger
public static AtomicInteger j = new AtomicInteger(0);
private static class MyRunnable implements Runnable{
@Override
public void run() {
//模拟其他业务操作 休眠一秒代替
SleepTools.second(1);
//getAndIncrement 以原子方式将当前值加1,注意,这里返回的是自增前的值
int andIncrement = j.getAndIncrement();
System.out.println(Thread.currentThread().getName() + "取值......." + andIncrement);
}
}
public static void main(String[] args) {
for(int i = 0;i<5;i++) {
new Thread(new MyRunnable()).start();
}
SleepTools.second(5);
System.out.println("main is ended!"+j);
}
运行结果:
Thread-0取值.......2
Thread-4取值.......1
Thread-2取值.......3
Thread-3取值.......0
Thread-1取值.......4
main is ended!5