zoukankan      html  css  js  c++  java
  • 并发编程——java线程基础之线程同步

    实现java线程同步的主要方法

    • synchronized关键字
    • 可重入锁

    synchronized的应用

      synchronized可以修饰代码块和方法,对代码块的加锁范围可以是类级别和对象级别,方法加锁本质上是对象级别加锁。

      对象级别加锁

     1 package base.synchronize;
     2 
     3 public class Thread1 implements Runnable{
     4     private Object obj;
     5     
     6     public Thread1(Object obj) {
     7         this.obj = obj;
     8     }
     9 
    10     @Override
    11     public void run() {
    12         synchronized (obj) {
    13             System.out.println(Thread.currentThread().getName() + ": start...");
    14             try {
    15                 Thread.sleep(10 * 1000);
    16             } catch (InterruptedException e) {
    17                 // TODO Auto-generated catch block
    18                 e.printStackTrace();
    19             }
    20             System.out.println(Thread.currentThread().getName() + ": end!");
    21         }
    22     }
    23 
    24 }
    对象级别加锁线程类
     1 package base.synchronize;
     2 
     3 import org.junit.Test;
     4 
     5 public class SynchronizeObject {
     6     public Object obj = new Object();
     7     
     8     @Test
     9     public void testFunc() {
    10         Thread t1 = new Thread(new Thread1(obj), "t1");
    11         Thread t2 = new Thread(new Thread1(obj), "t2");
    12         
    13         t1.start();
    14         t2.start();
    15         
    16         try {
    17             t1.join();
    18             t2.join();
    19         } catch (InterruptedException e) {
    20             e.printStackTrace();
    21         }
    22     }
    23 }
    客户端

      类级别加锁

     1 package base.synchronize;
     2 
     3 public class Thread2 implements Runnable{
     4 
     5     @Override
     6     public void run() {
     7         synchronized (Thread2.class) {
     8             System.out.println(Thread.currentThread().getName() + ": start...");
     9             try {
    10                 Thread.sleep(10 * 1000);
    11             } catch (InterruptedException e) {
    12                 // TODO Auto-generated catch block
    13                 e.printStackTrace();
    14             }
    15             System.out.println(Thread.currentThread().getName() + ": end!");
    16         }
    17     }
    18 
    19 }
    类级别加锁线程类
     1 package base.synchronize;
     2 
     3 import org.junit.Test;
     4 
     5 public class SynchronizeClass {    
     6     @Test
     7     public void testFunc() {
     8         Thread t1 = new Thread(new Thread2(), "t1");
     9         Thread t2 = new Thread(new Thread2(), "t2");
    10         
    11         t1.start();
    12         t2.start();
    13         
    14         try {
    15             t1.join();
    16             t2.join();
    17         } catch (InterruptedException e) {
    18             e.printStackTrace();
    19         }
    20     }
    21 }
    客户端

      方法级别加锁

     1 package base.synchronize;
     2 
     3 public class Thread3 implements Runnable{
     4 
     5     @Override
     6     public void run() {
     7         function();
     8     }
     9     
    10     public synchronized void function() {
    11         System.out.println(Thread.currentThread().getName() + ": start...");
    12         try {
    13             Thread.sleep(10 * 1000);
    14         } catch (InterruptedException e) {
    15             // TODO Auto-generated catch block
    16             e.printStackTrace();
    17         }
    18         System.out.println(Thread.currentThread().getName() + ": end!");
    19     }
    20 
    21 }
    方法级别加锁线程类
     1 package base.synchronize;
     2 
     3 import org.junit.Test;
     4 
     5 public class SynchronizeFunc {
     6     @Test
     7     public void testFunc() {
     8         Thread3 t = new Thread3();
     9         Thread t3 = new Thread(t, "t3");
    10         Thread t4 = new Thread(t, "t4");
    11         
    12         t3.start();
    13         t4.start();
    14         
    15         try {
    16             t3.join();
    17             t4.join();
    18         } catch (InterruptedException e) {
    19             e.printStackTrace();
    20         }
    21     }
    22 }
    客户端

    可重入锁的应用

      可重入锁(ReentrantLock)含义是,当一个线程获取了某一个可重入锁后可以再次去获取该可重入锁。其中分为普通的可重入锁以及读写锁。

      可重入锁的使用

     1 package base.lock;
     2 
     3 import java.util.concurrent.locks.ReentrantLock;
     4 
     5 public class Thread1 implements Runnable{
     6     private ReentrantLock lock;
     7     
     8     public Thread1(ReentrantLock lock) {
     9         this.lock = lock;
    10     }
    11 
    12     @Override
    13     public void run() {
    14         lock.lock();
    15         System.out.println(Thread.currentThread().getName() + ": start...");
    16         try {
    17             Thread.sleep(5 * 1000);
    18         } catch (InterruptedException e) {
    19             // TODO Auto-generated catch block
    20             e.printStackTrace();
    21         }
    22         System.out.println(Thread.currentThread().getName() + ": end.");
    23         lock.unlock();
    24     }
    25 
    26 }
    添加可重入锁的线程类
     1 package base.lock;
     2 
     3 import java.util.concurrent.locks.ReentrantLock;
     4 
     5 import org.junit.Test;
     6 
     7 public class LockMain {
     8     ReentrantLock lock = new ReentrantLock();
     9     
    10     @Test
    11     public void testCase() throws InterruptedException {
    12         Thread1 runnable = new Thread1(lock);
    13         Thread t1 = new Thread(runnable, "t1");
    14         Thread t2 = new Thread(runnable, "t2");
    15         
    16         t1.start();
    17         t2.start();
    18         
    19         t1.join();
    20         t2.join();
    21     }
    22 }
    客户端

      读写锁的使用

      读写锁,可以使用更细粒度的锁。读写锁的原则,读读共享、读写互斥、写写互斥。并且当有一个线程获取到了读锁且有一个线程获取写锁阻塞时,后来的读锁一定排队在该写锁之后才能获取资源,这是为了防止饥饿现象的发生(多运行几次读写混合客户端,观察不同的执行结果,分析执行结果不同的原因)

     1 package base.lock.readwritelock;
     2 
     3 import java.util.concurrent.locks.ReentrantReadWriteLock;
     4 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
     5 
     6 public class Thread1 implements Runnable{
     7     private ReentrantReadWriteLock lock;
     8     
     9     public Thread1(ReentrantReadWriteLock lock) {
    10         this.lock = lock;
    11     }
    12 
    13     @Override
    14     public void run() {
    15         WriteLock writeLock = lock.writeLock();
    16         writeLock.lock();
    17         System.out.println(Thread.currentThread().getName() + ": 写数据start...");
    18         try {
    19             Thread.sleep(5 * 1000);
    20         } catch (InterruptedException e) {
    21             // TODO Auto-generated catch block
    22             e.printStackTrace();
    23         }
    24         System.out.println(Thread.currentThread().getName() + ": 写数据end.");
    25         writeLock.unlock();
    26 
    27     }
    28 
    29 }
    写数据线程类
     1 package base.lock.readwritelock;
     2 
     3 import java.util.concurrent.locks.ReentrantReadWriteLock;
     4 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
     5 
     6 public class Thread2 implements Runnable{
     7     private ReentrantReadWriteLock lock;
     8     
     9     public Thread2(ReentrantReadWriteLock lock) {
    10         this.lock = lock;
    11     }
    12 
    13     @Override
    14     public void run() {
    15         ReadLock readLock = lock.readLock();
    16         readLock.lock();
    17         System.out.println(Thread.currentThread().getName() + ": 读数据start...");
    18         try {
    19             Thread.sleep(5 * 1000);
    20         } catch (InterruptedException e) {
    21             // TODO Auto-generated catch block
    22             e.printStackTrace();
    23         }
    24         System.out.println(Thread.currentThread().getName() + ": 读数据end.");
    25         readLock.unlock();
    26 
    27     }
    28 
    29 }
    读数据线程类
     1 package base.lock.readwritelock;
     2 
     3 import java.util.concurrent.locks.ReentrantReadWriteLock;
     4 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
     5 
     6 public class Thread2 implements Runnable{
     7     private ReentrantReadWriteLock lock;
     8     
     9     public Thread2(ReentrantReadWriteLock lock) {
    10         this.lock = lock;
    11     }
    12 
    13     @Override
    14     public void run() {
    15         ReadLock readLock = lock.readLock();
    16         readLock.lock();
    17         System.out.println(Thread.currentThread().getName() + ": 读数据start...");
    18         try {
    19             Thread.sleep(5 * 1000);
    20         } catch (InterruptedException e) {
    21             // TODO Auto-generated catch block
    22             e.printStackTrace();
    23         }
    24         System.out.println(Thread.currentThread().getName() + ": 读数据end.");
    25         readLock.unlock();
    26 
    27     }
    28 
    29 }
    纯写客户端
     1 package base.lock.readwritelock;
     2 
     3 import java.util.concurrent.locks.ReentrantLock;
     4 import java.util.concurrent.locks.ReentrantReadWriteLock;
     5 
     6 import org.junit.Test;
     7 
     8 public class ReadLockMain {
     9     ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    10     
    11     @Test
    12     public void testCase() throws InterruptedException {
    13         
    14         Thread2 runnable = new Thread2(lock);
    15         Thread t1 = new Thread(runnable, "t1");
    16         Thread t2 = new Thread(runnable, "t2");
    17 
    18         t1.start();
    19         t2.start();
    20         
    21         t1.join();
    22         t2.join();
    23     }
    24 }
    纯读客户端
     1 package base.lock.readwritelock;
     2 
     3 import java.util.concurrent.locks.ReentrantReadWriteLock;
     4 
     5 import org.junit.Test;
     6 
     7 public class ReadWriteLockMain {
     8     ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
     9     
    10     @Test
    11     public void testCase() throws InterruptedException {
    12         
    13         Thread1 runnable1 = new Thread1(lock);
    14         Thread2 runnable2 = new Thread2(lock);
    15         Thread t1 = new Thread(runnable1, "t1");
    16         Thread t2 = new Thread(runnable2, "t2");
    17         Thread t3 = new Thread(runnable2, "t3");
    18 
    19         t2.start();
    20         t1.start();
    21         t3.start();
    22 
    23         
    24         t1.join();
    25         t2.join();
    26         t3.join();
    27     }
    28 }
    读写混合客户端
  • 相关阅读:
    git 一般的使用操作
    php 导出excel,csv
    安装sublime_text_3
    安装mongodb记录,mongo基本命令记录
    redis 安装记录
    YII2 activeform样式修改
    go 安装下载
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hbsjz/com.hbsjz.BaseMapActivity}:
    SQLServer创建触发器,更新表
    SQL Server触发器创建、删除、修改、查看示例步骤
  • 原文地址:https://www.cnblogs.com/qq455988971/p/8252618.html
Copyright © 2011-2022 走看看