【多线程,详细demo】Java多线程基础学习(二)

心已赠人 2024-04-01 18:11 223阅读 0赞

9. 线程安全/共享变量——同步

当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次。这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”。

为了解决线程安全的问题,我们可以使用“同步”来控制线程访问。当一个线程在使用这个共享资源(不仅仅是变量,还可以是集合、对象等)的时候,其他线程就无法访问。

  1. package threadStudy;
  2. public class ThreadSynchronizedTest {
  3. public static void main(String[] args) throws InterruptedException{
  4. int i=0;
  5. ObjA o = new ObjA(i);
  6. TheThread theThread1 = new TheThread(o);
  7. TheThread theThread2 = new TheThread(o);
  8. theThread1.start();
  9. theThread2.start();
  10. }
  11. static class TheThread extends Thread{
  12. private ObjA objA;
  13. public TheThread(ObjA objA){
  14. this.objA = objA;
  15. }
  16. public void run(){
  17. objA.method();
  18. }
  19. }
  20. static class ObjA{
  21. int i;
  22. public ObjA(int i){
  23. this.i = i;
  24. }
  25. synchronized public void method(){
  26. for (int j=0;j<10;j++){
  27. i++;
  28. System.out.println(Thread.currentThread().getName()+ ": " + i);
  29. try{
  30. Thread.sleep(200);
  31. }catch(InterruptedException e){
  32. e.printStackTrace();
  33. }
  34. }
  35. }
  36. }
  37. }

以上述代码为例,如果加了关键字synchronized,则一个线程在使用共享资源o时,另一个线程必须等到前一个线程使用完,才能使用。

synchronized的输出结果:

1ba377bb029f6cc591e260facfd3d6fd.png

而不加synchronized的输出结果:

ae8f497fc657871a8bee23dc9802b75a.png

10. 容器类并发问题的同步解决方法

JDK中提供了并发容器,可以直接帮我们解决容器类出现的并发问题。它们大部分都存在java.util.concurrent这个包中,包括:ConcurrentHashmap,CopyOnWriteArrayList,ConcurrentLinkedQueue,BlockingQueue,ConcurrentSkipListMap。下面是使用ConcurrentHashmap解决Map容器并发问题的例子:

  1. package threadStudy;
  2. import java.util.Collections;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. public class ThreadConcurrencyCollectionTest {
  6. public static void main(String[] args) {
  7. Thread thread1 = new Thread(new HashTest.AddThread(0), "T0");
  8. Thread thread2 = new Thread(new HashTest.AddThread(1), "T1");
  9. thread1.start();
  10. thread2.start();
  11. }
  12. }
  13. class HashTest{
  14. //static Map<String, String> map = new HashMap<String, String>();
  15. static Map<String, String> map = Collections.synchronizedMap(new HashMap<String, String>());
  16. public static class AddThread extends Thread{
  17. private int start;
  18. public AddThread(int start){
  19. this.start = start;
  20. }
  21. public void run(){
  22. for (int i=start; i<10000; i+=2){
  23. System.out.println(Integer.toString(i));
  24. map.put(Integer.toString(i), Integer.toBinaryString(i));
  25. }
  26. }
  27. }
  28. }

发表评论

表情:
评论列表 (有 0 条评论,223人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java线基础

    Java多线程理解 一、常用方法 1、join()方法,让一个线程等待另一个线程执行完之后再执行。例如:A线程执行体中执行B线程的join方法,那么需要等到B线程执行