java高并发全局变量共享问题(解决多个用户同时访问造成数据错乱)

         先看下面问题:多个线程访问全局变量x,然后将x与i累加,启动10个线程,想让每个线程的输出结果都是一样的55,但是实际不是的。

注意:多个接口共享则全局变量为空
  1. package ThreadTest;
  2. public class Counter {
  3. private int x = 0;
  4. // 计数方法
  5. public void count() {
  6. for( int i= 0;i<= 10;i++) {
  7. x = x+i;
  8. }
  9. System.out.println(Thread.currentThread().getName()+ "--"+x);
  10. }
  11. public static void main(String[] args) {
  12. // 定义线程实现接口
  13. Runnable runnable = new Runnable(){
  14. Counter counter = new Counter();
  15. @Override
  16. public void run() {
  17. counter.count();
  18. }
  19. };
  20. // 启动10个线程
  21. for( int i= 0;i< 10;i++) {
  22. new Thread(runnable).start();
  23. }
  24. }
  25. }

            实际输出是无规则的。

解决方案一:


 
 
  1. package ThreadTest;
  2. public class Counter {
  3. ThreadLocal<Integer> th= new ThreadLocal<Integer>(){
  4. protected Integer initialValue() {
  5. return 0;
  6. }
  7. };
  8. // 计数方法
  9. public void count() {
  10. for( int i= 0;i<= 10;i++) {
  11. th.set(th.get()+i);
  12. }
  13. System.out.println(Thread.currentThread().getName()+ "--"+th.get());
  14. }
  15. }

用ThreadLocal,输出结果是55,ok!

由此可以证明,ThreadLocal为每一个线程保存每一个变量,而且每个线程拿到的都是自己的那一份。

解决方案二:

将全局变量局部化


 
 
  1. public class Count {
  2. public void count() {
  3. int x = 0;
  4. for( int i = 1; i <= 10; i++) {
  5. x=x+i;
  6. }
  7. System.out.println(Thread.currentThread().getName() + "-" + x);
  8. }
  9. }

每个线程都有一份自己的局部变量,因此不会产生线程问题。

解决方案三:对象局部化


 
 
  1. public static void main(String[] args) {
  2. Runnable runnable = new Runnable() {
  3. public void run() {
  4. Count count = new Count();
  5. count.count();
  6. }
  7. };
  8. for( int i = 0; i < 10; i++) {
  9. new Thread(runnable).start();
  10. }
  11. }

每个对象都会有一个自己的全局变量。不会产生线程问题。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Tornado是一个Python的Web框架,提供高性能的非阻塞网络IO,支持异步编程,能够很好地处理高并发的网络请求。而WebSocket是一种基于TCP协议的网络通信协议,与HTTP协议不同,WebSocket可以在客户端和服务器之间建立持久性的连接,实现双向实时通信。 在Tornado中,我们可以使用全局变量共享变量,也可以使用协程(Coroutine)来实现异步的变量共享。在WebSocket中,我们可以使用WebSocketHandler类来实现客户端和服务器之间的通信,并在类中定义成员变量共享变量。由于WebSocket是一种长连接,所以在客户端和服务器之间保持连接期间,这些成员变量会一直存在并且可被访问。 以下是一个简单的示例代码,展示了如何在Tornado和WebSocket中共享变量: ``` import tornado.ioloop import tornado.web import tornado.websocket # 全局变量 global_var = 0 # 定义WebSocketHandler类 class MyWebSocketHandler(tornado.websocket.WebSocketHandler): # 成员变量 member_var = 0 def open(self): print("WebSocket opened") # 共享全局变量 global global_var global_var += 1 # 修改成员变量 self.member_var += 1 def on_message(self, message): print("Received message: {}".format(message)) def on_close(self): print("WebSocket closed") # 定义HTTP请求处理类 class MainHandler(tornado.web.RequestHandler): def get(self): # 访问全局变量 global global_var self.write("Global variable: {}\n".format(global_var)) # 访问成员变量 ws = MyWebSocketHandler() self.write("Member variable: {}\n".format(ws.member_var)) # 定义应用程序对象 application = tornado.web.Application([ (r"/", MainHandler), (r"/ws", MyWebSocketHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.current().start() ``` 相关问题: 1. 什么是Tornado? 2. 什么是WebSocket? 3. Tornado如何实现非阻塞网络IO? 4. WebSocket和HTTP有什么区别? 5. 如何在Python中使用协程?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值