zoukankan      html  css  js  c++  java
  • Java多线程基础学习(二)

    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容器并发问题的例子:

     1 package threadStudy;
     2 
     3 import java.util.Collections;
     4 import java.util.HashMap;
     5 import java.util.Map;
     6 
     7 public class ThreadConcurrencyCollectionTest {
     8 
     9     public static void main(String[] args) {
    10         Thread thread1 = new Thread(new HashTest.AddThread(0), "T0");
    11         Thread thread2 = new Thread(new HashTest.AddThread(1), "T1");
    12         thread1.start();
    13         thread2.start();
    14 
    15     }
    16     
    17 }
    18 
    19 class HashTest{
    20     //static Map<String, String> map = new HashMap<String, String>();
    21     static Map<String, String> map = Collections.synchronizedMap(new HashMap<String, String>());
    22     public static class AddThread extends Thread{
    23         private int start;
    24         public AddThread(int start){
    25             this.start = start;
    26         }
    27         public void run(){
    28             for (int i=start; i<10000; i+=2){
    29                 System.out.println(Integer.toString(i));
    30                 map.put(Integer.toString(i), Integer.toBinaryString(i));
    31             }
    32         }
    33             
    34     }
    35 }
    zni.feng@gmail.com
  • 相关阅读:
    【Linux】【Shell】【Basic】文件查找locate,find
    【Linux】【Shell】【text】Vim
    【Linux】【Shell】【text】文本处理工具
    【Linux】【Shell】【text】grep
    【Linux】【Basis】用户、组和权限管理
    什么是高并发;超发的解决思路(悲观锁与乐观锁);高并发与多线程的关系--持续更新(十四)
    线程池的应用(十三)
    线程池基本概念(十二)
    ThreadLocal(十一)
    tomcat的单例多线程代码示例(十)
  • 原文地址:https://www.cnblogs.com/znicy/p/5681282.html
Copyright © 2011-2022 走看看