并发编程系列小结(线程安全,synchronized,脏读,线程间的通信wait/notify,线程的三种实现方式Demo,可替代wait/notify的方法)

线程安全:

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

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