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
原文地址:https://www.cnblogs.com/znicy/p/5681282.html