线程的并发

  在同一个时间点,N个线程访问同一个资源,会引发线程不安全问题!

解决办法:

  同步代码块和同步代码方法  synchronized  给线程上锁。

同步和异步的定义:

  同步(synchronous):也称阻塞。一个线程再去执行一个操作时,如果这个操作有一个值需要返回,那么所有线程需要等待这个操作结束,返回值得到以后才可以继续执行线程的抢占资源。

  异步(asynchronous):与同步不同的是,当一个线程的操作需要返回值是,其他线程不需要等待,可以去做其他的事情。

注意点:
  01.在同一个时间点,只有一个线程能进入synchronized修饰的方法或者代码块
  02.当一个线程访问synchronized代码块或者方法的时候,其他线程等待,其他synchronized代码块也会被锁定!
  03.当一个线程访问synchronized代码块或者方法的时候,其他的线程可以访问非synchronized修饰的代码块或者方法!

 1 /**
 2  * 售票的线程类    考虑并发  使用同步代码块
 3  */
 4 public class SaleThreadBlock implements Runnable {
 5     // 定义总票数
 6     private int counts = 100;
 7     // 定义出售的票数
 8     private int num = 0;
 9 
10     @Override
11     public void run() {
12         while (true) {
13             /**
14              *  在多个线程并发访问run()
15              *  只有一个线程能进入synchronized同步代码块,
16              *  只有当这个线程执行完毕,出来之后,其他线程才能进入
17              */
18             synchronized (this) {
19                 if (counts <= 0) {
20                     break; // 没有票 退出 循环
21                 }
22                 // 售票
23                 counts--;
24                 num++; // 记录出售的票数
25                 System.out.println(Thread.currentThread().getName() + "抢到了第"
26                         + num + "张票,剩余票数:" + counts);
27             }
28         }
29 
30     }
31 
32     // 测试方法
33     public static void main(String[] args) {
34         SaleThreadBlock block = new SaleThreadBlock();
35         // 创建线程对象
36         Thread t1 = new Thread(block, "张三");
37         Thread t2 = new Thread(block, "李四");
38         Thread t3 = new Thread(block, "王五");
39         Thread t4 = new Thread(block, "老黄牛");
40         System.out.println("============所有人 开始抢票============");
41         // 启动线程
42         t1.start();
43         t2.start();
44         t3.start();
45         t4.start();
46 
47     }
48 }
同步代码块方法
 1 /**
 2  * 售票的线程类    考虑并发  使用同步代码方法
 3  */
 4 public class SaleThreadMethod implements Runnable {
 5     // 定义总票数
 6     private int counts = 100;
 7     // 定义出售的票数
 8     private int num = 0;
 9 
10     // 定义一个标记 票是否出售完毕
11     boolean flag = false;
12 
13     @Override
14     public void run() {
15         while (!flag) {
16             sale(); // 只要还有票 就一直出售
17         }
18 
19     }
20 
21     /**
22      *  在多个线程并发访问run()
23      *  只有一个线程能进入synchronized同步代码方法,
24      *  只有当这个线程执行完毕,出来之后,其他线程才能进入
25      */
26     public synchronized void sale() {
27         if (counts <= 0) {
28             flag = true;
29             return; // 没有票 退出 循环
30         }
31         // 售票
32         counts--;
33         num++; // 记录出售的票数
34         System.out.println(Thread.currentThread().getName() + "抢到了第" + num
35                 + "张票,剩余票数:" + counts);
36     }
37 
38     // 测试方法
39     public static void main(String[] args) {
40         SaleThreadMethod block = new SaleThreadMethod();
41         // 创建线程对象
42         Thread t1 = new Thread(block, "张三");
43         Thread t2 = new Thread(block, "李四");
44         Thread t3 = new Thread(block, "王五");
45         Thread t4 = new Thread(block, "老黄牛");
46         System.out.println("============所有人 开始抢票============");
47         // 启动线程
48         t1.start();
49         t2.start();
50         t3.start();
51         t4.start();
52 
53     }
54 }
同步代码方法
原文地址:https://www.cnblogs.com/ak666/p/8184081.html