package org;
import java.util.Random;
public class MockMain {
//交易总金额
public static int money =0;
public static void main(String[] args) {
//模拟多线程,
for(int i=0;i<5;i++){
new Thread(new Runnable() {
public void run() {
//商品金额
money = new Random().nextInt(500);
System.out.println("main 线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.money);
//检查账号金额是否大于商品金额
AccountMoney account = new AccountMoney();
account.check();
//扣款
LoseMoney lose = new LoseMoney();
lose.outMoney();
}
}).start();
}
}
}
package org;
public class AccountMoney {
public void check(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.money);
}
}
package org;
public class LoseMoney {
public void outMoney(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";扣款金额:"+MockMain.money);
}
}
输出日志:
main 线程id:10;商品金额:141
main 线程id:9;商品金额:130
main 线程id:11;商品金额:51
main 线程id:12;商品金额:51
线程id:10;商品金额:51
线程id:8;商品金额:51
线程id:12;商品金额:51
线程id:9;商品金额:51
线程id:11;商品金额:51
线程id:12;扣款金额:51
线程id:11;扣款金额:51
线程id:8;扣款金额:51
线程id:10;扣款金额:51
线程id:9;扣款金额:51
从日志中可以看出,线程中检查的金额 ,扣除的金额是不对的。 线程10 的商品金额应该为:141,但是检查和扣除是变成了51; 线程9 的商品金额应该为:130,但是检查和扣除是变成了51 . 线程还没有工作完毕,就被其它的线程打断了,可以考虑加锁看看是否解决 线程和金额混乱的问题。对MockMain 进行修改,修改后如下:
package org;
import java.util.Random;
public class MockMain {
public static final Integer lock =1;
//交易总金额
public static int money =0;
public static void main(String[] args) {
//模拟多线程,
for(int i=0;i<5;i++){
new Thread(new Runnable() {
public void run() {
synchronized (lock) {
//商品金额
money = new Random().nextInt(500);
System.out.println("main 线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.money);
//检查账号金额是否大于商品金额
AccountMoney account = new AccountMoney();
account.check();
//扣款
LoseMoney lose = new LoseMoney();
lose.outMoney();
}
}
}).start();
}
}
}
输出日志:
main 线程id:8;商品金额:439
线程id:8;商品金额:439
线程id:8;扣款金额:439
main 线程id:12;商品金额:172
线程id:12;商品金额:172
线程id:12;扣款金额:172
main 线程id:11;商品金额:300
线程id:11;商品金额:300
线程id:11;扣款金额:300
main 线程id:10;商品金额:128
线程id:10;商品金额:128
线程id:10;扣款金额:128
main 线程id:9;商品金额:459
线程id:9;商品金额:459
线程id:9;扣款金额:459
从日志看,已经可以实现了线程和金额的同步,但是我们添加了锁效率会很低,只有一个线程执行完成后,下一个线程才会执行。有没有更高的效率来实现呢。
我们可以变量和线程绑定试一下。代码修改如下:
package org;
import java.util.Random;
public class MockMain {
public static final Integer lock =1;
public static ThreadLocal<Integer> moneyStore = new ThreadLocal<Integer>();
public static void main(String[] args) {
//模拟多线程,
for(int i=0;i<5;i++){
new Thread(new Runnable() {
public void run() {
//商品金额
Integer money = new Random().nextInt(500);
//变量和线程绑定
moneyStore.set(money);
System.out.println("main 线程id:"+Thread.currentThread().getId()
+";商品金额:"+money +"; moneyStore="+moneyStore.get());
//检查账号金额是否大于商品金额
AccountMoney account = new AccountMoney();
account.check();
//扣款
LoseMoney lose = new LoseMoney();
lose.outMoney();
}
}).start();
}
}
}
package org;
public class AccountMoney {
public void check(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.moneyStore.get());
}
}
package org;
public class LoseMoney {
public void outMoney(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";扣款金额:"+MockMain.moneyStore.get());
}
}
日志输出:
main 线程id:10;商品金额:320; moneyStore=320
main 线程id:11;商品金额:252; moneyStore=252
main 线程id:8;商品金额:116; moneyStore=116
main 线程id:12;商品金额:56; moneyStore=56
线程id:11;商品金额:252
线程id:12;商品金额:56
线程id:10;商品金额:320
线程id:9;商品金额:468
线程id:8;商品金额:116
线程id:11;扣款金额:252
线程id:10;扣款金额:320
线程id:9;扣款金额:468
线程id:8;扣款金额:116
线程id:12;扣款金额:56
从日志看,线程是并发的,是同时进行的,金额和线程没有混乱,因为没有使用锁,并发效率很高。
因此,使用这种方法实现高并发是安全可靠的。
import java.util.Random;
public class MockMain {
//交易总金额
public static int money =0;
public static void main(String[] args) {
//模拟多线程,
for(int i=0;i<5;i++){
new Thread(new Runnable() {
public void run() {
//商品金额
money = new Random().nextInt(500);
System.out.println("main 线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.money);
//检查账号金额是否大于商品金额
AccountMoney account = new AccountMoney();
account.check();
//扣款
LoseMoney lose = new LoseMoney();
lose.outMoney();
}
}).start();
}
}
}
package org;
public class AccountMoney {
public void check(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.money);
}
}
package org;
public class LoseMoney {
public void outMoney(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";扣款金额:"+MockMain.money);
}
}
输出日志:
main 线程id:10;商品金额:141
main 线程id:9;商品金额:130
main 线程id:11;商品金额:51
main 线程id:12;商品金额:51
线程id:10;商品金额:51
线程id:8;商品金额:51
线程id:12;商品金额:51
线程id:9;商品金额:51
线程id:11;商品金额:51
线程id:12;扣款金额:51
线程id:11;扣款金额:51
线程id:8;扣款金额:51
线程id:10;扣款金额:51
线程id:9;扣款金额:51
从日志中可以看出,线程中检查的金额 ,扣除的金额是不对的。 线程10 的商品金额应该为:141,但是检查和扣除是变成了51; 线程9 的商品金额应该为:130,但是检查和扣除是变成了51 . 线程还没有工作完毕,就被其它的线程打断了,可以考虑加锁看看是否解决 线程和金额混乱的问题。对MockMain 进行修改,修改后如下:
package org;
import java.util.Random;
public class MockMain {
public static final Integer lock =1;
//交易总金额
public static int money =0;
public static void main(String[] args) {
//模拟多线程,
for(int i=0;i<5;i++){
new Thread(new Runnable() {
public void run() {
synchronized (lock) {
//商品金额
money = new Random().nextInt(500);
System.out.println("main 线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.money);
//检查账号金额是否大于商品金额
AccountMoney account = new AccountMoney();
account.check();
//扣款
LoseMoney lose = new LoseMoney();
lose.outMoney();
}
}
}).start();
}
}
}
输出日志:
main 线程id:8;商品金额:439
线程id:8;商品金额:439
线程id:8;扣款金额:439
main 线程id:12;商品金额:172
线程id:12;商品金额:172
线程id:12;扣款金额:172
main 线程id:11;商品金额:300
线程id:11;商品金额:300
线程id:11;扣款金额:300
main 线程id:10;商品金额:128
线程id:10;商品金额:128
线程id:10;扣款金额:128
main 线程id:9;商品金额:459
线程id:9;商品金额:459
线程id:9;扣款金额:459
从日志看,已经可以实现了线程和金额的同步,但是我们添加了锁效率会很低,只有一个线程执行完成后,下一个线程才会执行。有没有更高的效率来实现呢。
我们可以变量和线程绑定试一下。代码修改如下:
package org;
import java.util.Random;
public class MockMain {
public static final Integer lock =1;
public static ThreadLocal<Integer> moneyStore = new ThreadLocal<Integer>();
public static void main(String[] args) {
//模拟多线程,
for(int i=0;i<5;i++){
new Thread(new Runnable() {
public void run() {
//商品金额
Integer money = new Random().nextInt(500);
//变量和线程绑定
moneyStore.set(money);
System.out.println("main 线程id:"+Thread.currentThread().getId()
+";商品金额:"+money +"; moneyStore="+moneyStore.get());
//检查账号金额是否大于商品金额
AccountMoney account = new AccountMoney();
account.check();
//扣款
LoseMoney lose = new LoseMoney();
lose.outMoney();
}
}).start();
}
}
}
package org;
public class AccountMoney {
public void check(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";商品金额:"+MockMain.moneyStore.get());
}
}
package org;
public class LoseMoney {
public void outMoney(){
System.out.println("线程id:"+Thread.currentThread().getId()
+";扣款金额:"+MockMain.moneyStore.get());
}
}
日志输出:
main 线程id:10;商品金额:320; moneyStore=320
main 线程id:11;商品金额:252; moneyStore=252
main 线程id:8;商品金额:116; moneyStore=116
main 线程id:12;商品金额:56; moneyStore=56
线程id:11;商品金额:252
线程id:12;商品金额:56
线程id:10;商品金额:320
线程id:9;商品金额:468
线程id:8;商品金额:116
线程id:11;扣款金额:252
线程id:10;扣款金额:320
线程id:9;扣款金额:468
线程id:8;扣款金额:116
线程id:12;扣款金额:56
从日志看,线程是并发的,是同时进行的,金额和线程没有混乱,因为没有使用锁,并发效率很高。
因此,使用这种方法实现高并发是安全可靠的。