Java多线程基础学习(二)
2016-07-29 14:54
267 查看
9. 线程安全/共享变量——同步
当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次。这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”。
为了解决线程安全的问题,我们可以使用“同步”来控制线程访问。当一个线程在使用这个共享资源(不仅仅是变量,还可以是集合、对象等)的时候,其他线程就无法访问。
以上述代码为例,如果加了关键字synchronized,则一个线程在使用共享资源o时,另一个线程必须等到前一个线程使用完,才能使用。
加synchronized的输出结果:
而不加synchronized的输出结果:
10. 容器类并发问题的同步解决方法
JDK中提供了并发容器,可以直接帮我们解决容器类出现的并发问题。它们大部分都存在java.util.concurrent这个包中,包括:ConcurrentHashmap,CopyOnWriteArrayList,ConcurrentLinkedQueue,BlockingQueue,ConcurrentSkipListMap。下面是使用ConcurrentHashmap解决Map容器并发问题的例子:
当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次。这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”。
为了解决线程安全的问题,我们可以使用“同步”来控制线程访问。当一个线程在使用这个共享资源(不仅仅是变量,还可以是集合、对象等)的时候,其他线程就无法访问。
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)); } } } }
相关文章推荐
- java基础学习--多线程
- java基础学习__多线程(停止线程,守护线程,join方法)
- java多线程基础学习-核心编程
- 黑马程序员 java基础 继承thread多线程学习日志
- Java多线程基础学习
- Java基础学习4_多线程(同步)
- 黑马程序员—10—java基础:有关多线程安全的学习笔记和学习心得体会
- java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)
- 黑马程序员—Java基础学习笔记之多线程
- 黑马程序员—java基础学习--多线程
- Java基础学习6_多线程(线程间通信--生产者消费者)
- 黑马程序员学习log第四篇基础知识:JAVA的面向对象之多线程总结
- java基础学习笔记_多线程
- java基础知识回顾之java Thread类学习(五)--java多线程安全问题(锁)同步的前提
- C\C++ 程序员从零开始学习Android - 个人学习笔记(十) - java基础 - 多线程(待续)
- Java基础学习__多线程(线程间通信--生产者消费者JDK5.0升级版)
- 黑马程序员---Java基础学习笔记(多线程-后篇)
- JAVA基础学习之throws和throw的区别、Java中的四种权限、多线程的使用等(2)
- Java基础学习——简介Java多线程
- java基础知识回顾之java Thread类学习(七)--java多线程安全问题(死锁)