前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >多线程线程安全问题

多线程线程安全问题

作者头像
用户1518699
发布2019-04-18 16:20:21
5080
发布2019-04-18 16:20:21
举报
文章被收录于专栏:nice_每一天nice_每一天

1.多线程的实现

多线程有两种实现方式:

1.1.继承Thread类 =>示例:A a=new A(); a.start();

1.2.实现Runnable接口 =>示例:A a=new A(); new Thread(A,自定义线程名称).start();

其实Thread和Runnable都实现了run方法,这种操作模式其实就是代理模式

获取当前线程名称:Thread.currentThread().getName()

调用线程是thread.start(),真正执行线程是 thread.run()

具体代码:

代码语言:javascript
复制
 1 /**
 2  * 继承Thread类
 3  * @date 2019/3/29 11:19
 4  */
 5 public class SimpleThread extends Thread{
 6 
 7     @Override
 8     public void run() {
 9         super.run();
10         Thread thread = Thread.currentThread();
11         System.out.println("Thread =>当前执行的线程为:"+thread.getName());
12     }
13 }
14 
15 /**
16  * 实现Runnable接口
17  * @date 2019/3/29 11:28
18  */
19 public class SimpleRunnable implements Runnable {
20 
21     @Override
22     public void run() {
23          Thread thread = Thread.currentThread();
24          System.out.println("Runnable =>当前执行的线程为:"+thread.getName());
25     }
26 }
27 
28 public class TestMain {
29 
30 
31     /**执行线程示例1*/
32     private static void callSimpleThread(){
33         int index=10;
34         for (int i = 0; i < index; i++) {
35              Thread thread=new SimpleThread();
36              thread.start();
37         }
38     }
39 
40     /**执行线程示例1*/
41     private static void callSimpleRunnable(){
42         int index=10;
43         for (int i = 0; i < index; i++) {
44             SimpleRunnable simpleRunnable=new SimpleRunnable();
45             new Thread(simpleRunnable,"Runnable-"+i).start();
46         }
47     }
48 
49     public static void main(String[] args) {
50 
51         callSimpleThread();
52 
53         callSimpleRunnable();
54     }
55 
56 }

2.多线程安全问题

2.1线程不安全示例

代码语言:javascript
复制
多线程最容易产生的一个问题就是线程安全问题,下面使用一个卖票的例子来体现。
代码语言:javascript
复制
场景描述:现在有两个售票员,一共卖10张车票
代码语言:javascript
复制
 1 public class SellTicket extends Thread {
 2 
 3     private static int NUMBER = 10;
 4     public SellTicket(String name) {
 5         super(name);
 6     }
 7 
 8     @Override
 9     public void run() {
10         String s = "线程:" + Thread.currentThread().getName();
11 
12         while (NUMBER > 0) {
13             int i = NUMBER--;
14             System.out.println(s + " => 卖了第" + i + "号票");
15         }
16 
17         System.out.println(s + ",票已经卖完");
18         super.run();
19     }
20 
21 
22     public static void main(String[] args) {
23 
24         SellTicket thread1 = new SellTicket("售票员A");
25         thread1.start();
26 
27         SellTicket thread2 = new SellTicket("售票员B");
28         thread2.start();
29 
30     }
31 
32 }

执行结果如下:

我们发现售票员A 和售票员B都卖了10号票,这就是线程不安全导致的结果

2.2线程不安全解决方法

代码语言:javascript
复制
方案一:使用同步代码解决
格式:synchronized(锁对象){需要被同步的代码}
锁对象可以为this锁,也可以自定义对象锁

方案二:使用同步函数解决
同步函数就是使用synchronized修饰一个函数

下面采用同步代码块解决

代码语言:javascript
复制
 1 public class SafetySellTicket extends Thread {
 2 
 3     private static int NUMBER = 10;
 4 
 5     @Override
 6     public  void run() {
 7         String s = "线程:" + Thread.currentThread().getName();
 8 
 9         while (NUMBER > 0) {
10             synchronized (this) {
11                 if (NUMBER > 0) {
12                     int i = NUMBER--;
13                     System.out.println(s + " => 卖了第" + i + "号票");
14                 } else {
15                     System.out.println(s + ",票已经卖完");
16                     break;
17                 }
18 
19             }
20         }
21         super.run();
22     }
23 
24 
25     public static void main(String[] args) {
26 
27         SafetySellTicket thread1 = new SafetySellTicket();
28         thread1.start();
29 
30         SafetySellTicket thread2 = new SafetySellTicket();
31         thread2.start();
32 
33     }
34 
35 }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.多线程的实现
    • 1.1.继承Thread类 =>示例:A a=new A(); a.start();
      • 1.2.实现Runnable接口 =>示例:A a=new A(); new Thread(A,自定义线程名称).start();
      • 2.多线程安全问题
        • 2.1线程不安全示例
          • 2.2线程不安全解决方法
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档