JAVA线程/并发/请求的关系是怎么样的?精华 -- 转载

JAVA线程/并发/请求的关系是怎么样的?精华

最近对线程并发请求有疑惑,度娘了一大圈,找了一些精华,真的很精华!!!!在此总结记录下:
转载连接如下:
https://bbs.csdn.net/topics/360170441
https://bbs.csdn.net/topics/360170441
https://www.zhihu.com/question/41737405/answer/100743322
https://www.cnblogs.com/GtShare/p/8033637.html(Servlet如何处理多个请求访问?下一篇马上进行搬运)
https://blog.csdn.net/weixin_39939904/article/details/114207476

用过socket就知道,很多用户同时发出请求,在一个时间点服务器只能处理一个用户的请求,如果你没有采用多线程的话,那么服务器只有处理完
当前用户的请求之后,才能处理下一个用户的请你。如果用了多线程,那么下个用户请求时就不用等到上个用户处理完再处理,而是可能某个时间点会切换到当前用户的请求处理。如果多线程之间没有数据共享,那么可以不用synchronized。

单线程和多线程的区别是在于 你每次是否操作同一个线程 如果是多线程 那么你读代码就会明白 每次 操作的是重新创建的线程
保证线程安全 有三种方式: 第一种 用ThreadLocal 定义变量 , 第二种 用同步锁 也就是你说的synchronized , 还有一种springmvc 和spring整合做项目的时候,注解的开发方式,就是使用局部变量,随着方法的消失而消失

1.多个用户访问同一段代码算多线程吗?
2.那怎么样控制并发?

不是, 多用户请求是并发,并发是多个用户或者说多个请求要同时对同一条记录进行操作,和是不是同一段代码没关系。好比说多个用户同时登陆一个系统时,都需要用到登陆的相关代码,是不会发生什么冲突的。好比说对一个财务系统,两个人同时对总钱数进行操作,一个加10块一个减100块,注意这两个操作是同时进行的,那系统就不知道是加还是减了,这是并发问题。加锁解决就是,在一个请求开始对这条记录操作时,其它的请求就不能对它操作了,直到现在正在进行的操作完成。

并发 和多线程之间联系和区别?

并发与多线程之间的关系就是目的与手段之间的关系。并发(Concurrent)的反面是串行。串行好比多个车辆行驶在一股车道上,它们只能“鱼贯而行”。而并发好比多个车辆行驶在多股车道上,它们可以“并驾齐驱”。并发的极致就是并行(Parallel)。多线程就是将原本可能是串行的计算“改为”并发(并行)的一种手段、途径或者模型。因此,有时我们也称多线程编程为并发编程。当然,目的与手段之间常常是一对多的关系。并发编程还有其他的实现途径,例如函数式(Functional programming)编程。多线程编程往往是其他并发编程模型的基础,所以多线程编程的重要性不言而喻。

controller中的全局变量如何解决????

Controller默认是单例的,不要使用非静态的成员变量,否则会发生数据逻辑混乱。 正因为单例所以不是线程安全的。

如下代码:

package com.riemann.springbootdemo.controller;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ScopeTestController {

	private int num = 0;

	@RequestMapping("/testScope")
	public void testScope() {

		System.out.println(++num);

	}

	@RequestMapping("/testScope2")
	public void testScope2() {

		System.out.println(++num);
	}
}

我们首先访问 http://localhost:8080/testScope,得到的答案是1; 然后我们再访问 http://localhost:8080/testScope2,得到的答案是 2。

得到的不同的值,这是线程不安全的。

接下来我们再来给Controller增加作用多例 @Scope(“prototype”)

package com.riemann.springbootdemo.controller;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@Scope("prototype")
public class ScopeTestController {

	private int num = 0;

	@RequestMapping("/testScope")
	public void testScope() {

		System.out.println(++num);

	}

	@RequestMapping("/testScope2")
	public void testScope2() {

		System.out.println(++num);

	}
}

我们依旧首先访问 http://localhost:8080/testScope,得到的答案是1; 然后我们再访问 http://localhost:8080/testScope2,得到的答案还是 1。

相信大家不难发现 :

单例是不安全的,会导致属性重复使用。

解决方案

1、不要在Controller中定义成员变量。 2、万一必须要定义一个非静态成员变量时候,则通过注解@Scope(“prototype”),将其设置为多例模式。 3、在Controller中使用ThreadLocal变量

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值