天天看点

Java多线程基础学习(二)

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

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

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的输出结果:

Java多线程基础学习(二)

而不加synchronized的输出结果:

Java多线程基础学习(二)
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));

              }

          }
  
      }

  }