欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

并发编程学习小结

程序员文章站 2022-03-29 17:11:01
线程安全: 当多个线程访问某一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法就是线程安全的) synchronized: 可以在任意对象或方法上加锁,而加锁的这段代码称为“互斥区”或“临界区” 多个线程多个锁: 多个线程都有自己对应的锁 脏读: 在我们对一个对象的方法或 ......

线程安全:

当多个线程访问某一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法就是线程安全的)

 

synchronized:

可以在任意对象或方法上加锁,而加锁的这段代码称为“互斥区”或“临界区”

 

多个线程多个锁:

多个线程都有自己对应的锁

 

脏读:

在我们对一个对象的方法或对象加锁时,需要考虑业务的整体性,即为setValue/getValue方法同时加锁synchronized同步关键字,保证业务的原子性,不然会出现业务错误(也从侧面保证了数据的一致性)

 

线程间的通信:

使用notify/wait方法实现线程间的通信(注意这两个方法都是object类的方法)

wait/ notify 必须配合synchronized关键字使用

wait方法释放锁,notify方法不释放锁

 

CountDownLatch与锁无关

 

线程的三种实现方式Demo

 1 package com.jonychen.test;
 2 
 3 import java.util.concurrent.Callable;
 4 import java.util.concurrent.ExecutionException;
 5 import java.util.concurrent.FutureTask;
 6 
 7 /**
 8  * 线程的三种实现方式
 9  */
10 public class TestDemo {
11 
12     public static void main(String[] args){
13      /**
14          * 第一种方式:继承Thread类重写run()方法
15          */
16         Thread thread=new ThreadDemo();
17         thread.start();
18 
19         /**
20          * 第二种方式:实现Runnable接口重写run()方法
21          */
22         RunnableDemo runnableDemo=new RunnableDemo();
23         Thread thread1=new Thread(runnableDemo);
24         thread1.start();
25         try {
26             thread1.sleep(3000);
27         } catch (InterruptedException e) {
28             e.printStackTrace();
29         }
30 
31         /**
32          * 第三种方式:实现Callable接口重写call()方法
33          */
34         CallableDemo  callableDemo =new CallableDemo();
35         FutureTask<Integer> futureTask=new FutureTask<Integer>(callableDemo);
36         Thread thread2=new Thread(futureTask);
37         thread2.start();
38         try {
39             System.out.println("返回的参数为:"+futureTask.get());
40         } catch (InterruptedException e) {
41             e.printStackTrace();
42         } catch (ExecutionException e) {
43             e.printStackTrace();
44         }
45     }
46 }
47 
48 /**
49  * 第一种方式:继承Thread类重写run()方法
50  */
51 class ThreadDemo extends Thread{
52     @Override
53     public void run() {
54         System.out.println("我是继承Thread类实现线程的一种方式!");
55     }
56 }
57 
58 /**
59  * 第二种方式:实现Runnable接口重写run()方法
60  */
61 class  RunnableDemo implements  Runnable{
62     @Override
63     public void run() {
64         System.out.println("我是实现Runnable接口实现线程的一种方式");
65     }
66 }
67 
68 /**
69  * 第三种方式:实现Callable接口重写call()方法
70  */
71 class  CallableDemo implements Callable<Integer>{
72 
73     @Override
74     public Integer call(){
75         return 666666;
76     }
77 }

输出截图:

并发编程学习小结

 

可替代wait/notify的方法

 1 package com.jonychen.test;
 2 
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 import java.util.concurrent.locks.Condition;
 6 import java.util.concurrent.locks.Lock;
 7 import java.util.concurrent.locks.ReentrantLock;
 8 
 9 /**
10  *java.util.concurrent 类库中提供了 Condition 类来实现线程之间的协调,可以在 Condition 上调用 await() 方法使线程等待,
11  * 其它线程调用 signal() 或 signalAll() 方法唤醒等待的线程。
12  * 相比于 wait() 这种等待方式,await() 可以指定等待的条件,因此更加灵活。
13  *
14  * 使用 Lock 来获取一个 Condition 对象。
15  */
16 public class ConcurrentDemo {
17 
18     private Lock lock=new ReentrantLock();
19     private Condition condition=lock.newCondition();
20 
21     public  void before(){
22         lock.lock();
23         try {
24             System.out.println("before");
25             condition.signalAll();
26         } finally {
27             lock.unlock();
28         }
29     }
30 
31     public  void after(){
32        lock.lock();
33         try {
34             condition.await();
35             System.out.println("after");
36         } catch (InterruptedException e) {
37             e.printStackTrace();
38         } finally {
39             lock.unlock();
40         }
41 
42     }
43 
44     public static void main(String[] args){
45 
46         ExecutorService executorService  =Executors.newCachedThreadPool();
47         ConcurrentDemo concurrentDemo=new ConcurrentDemo();
48         executorService.execute(()->concurrentDemo.after());
49         executorService.execute(()->concurrentDemo.before());
50     }
51 
52 }