Java多线程基础学习(二)
2024-10-01 20:57:43
9. 线程安全/共享变量——同步
当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次。这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”。
为了解决线程安全的问题,我们可以使用“同步”来控制线程访问。当一个线程在使用这个共享资源(不仅仅是变量,还可以是集合、对象等)的时候,其他线程就无法访问。
package threadStudy; public class ThreadSynchronizedTest { public static void main(String[] args) throws InterruptedException{
int i=0;
ObjA o = new ObjA(i);
TheThread theThread1 = new TheThread(o);
TheThread theThread2 = new TheThread(o);
theThread1.start();
theThread2.start();
} static class TheThread extends Thread{
private ObjA objA;
public TheThread(ObjA objA){
this.objA = objA;
}
public void run(){
objA.method();
}
} static class ObjA{
int i;
public ObjA(int i){
this.i = i;
}
synchronized public void method(){
for (int j=0;j<10;j++){
i++;
System.out.println(Thread.currentThread().getName()+ ": " + i);
try{
Thread.sleep(200);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
}
以上述代码为例,如果加了关键字synchronized,则一个线程在使用共享资源o时,另一个线程必须等到前一个线程使用完,才能使用。
加synchronized的输出结果:
而不加synchronized的输出结果:
10. 容器类并发问题的同步解决方法
JDK中提供了并发容器,可以直接帮我们解决容器类出现的并发问题。它们大部分都存在java.util.concurrent这个包中,包括:ConcurrentHashmap,CopyOnWriteArrayList,ConcurrentLinkedQueue,BlockingQueue,ConcurrentSkipListMap。下面是使用ConcurrentHashmap解决Map容器并发问题的例子:
package threadStudy; import java.util.Collections;
import java.util.HashMap;
import java.util.Map; public class ThreadConcurrencyCollectionTest { public static void main(String[] args) {
Thread thread1 = new Thread(new HashTest.AddThread(0), "T0");
Thread thread2 = new Thread(new HashTest.AddThread(1), "T1");
thread1.start();
thread2.start(); } } class HashTest{
//static Map<String, String> map = new HashMap<String, String>();
static Map<String, String> map = Collections.synchronizedMap(new HashMap<String, String>());
public static class AddThread extends Thread{
private int start;
public AddThread(int start){
this.start = start;
}
public void run(){
for (int i=start; i<10000; i+=2){
System.out.println(Integer.toString(i));
map.put(Integer.toString(i), Integer.toBinaryString(i));
}
} }
}
最新文章
- 计算机程序的思维逻辑 (41) - 剖析HashSet
- RHEL6.5安装11.2.0.3 RAC并打补丁
- .jshintrc配置
- 在阿里云主机上基于CentOS用vsftpd搭建FTP服务器
- NSString和SwiftString的区别和使用场景
- Python学习教程(learning Python)--2.1 Python下自定义函数
- Connectify是一款很实用的免费软件。能把计算机变成一个无线路由器
- 初探—KMP模式匹配算法
- BT5之配置笔记
- Android 设计模式实战之关于封装计费代码库的策略模式详谈
- 在Eclipse中如何关联源代码
- antlr v4 使用指南连载3——g4文件概览
- 如何写一个好的缺陷(Defect)报告
- 解决IntelliJ IDEA无法读取配置*.properties文件的问题
- AngularJS中监视Scope变量以及外部调用Scope方法
- Python3用gevent写个文件字符串查找器
- 页面中href链接的碰撞
- Luogu1445 [Violet]樱花 ---- 数论优化
- RabbitMQ入门_07_Fanout 与 Topic
- php拓展安装
热门文章
- 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题
- mysql每秒最多能插入多少条数据 ? 死磕性能压测
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库
- H5坦克大战之【建造敌人的坦克】
- MVC Core 网站开发(Ninesky) 2、栏目
- 集合(set)-Python3
- Lind.DDD.Aspects通过Plugins实现方法的动态拦截~Lind里的AOP
- hibernate的基本xml文件配置
- 电信计费业务:预后融合OCS到底应该实扣还是虚扣?
- Android—关于自定义对话框的工具类