线程的安全问题的解决方法-同步方法

同步方法

如果操作共享数据的代码完整的声明在一个方法中,我们可以将此方法声明同步的

一·实现类:

将要同步的方法单独挑选出来

package new1;


public class demo4 {
    public static void main(String[] args) {
       Window1 w = new Window1(); //此时只造了一个对象

       Thread t1 = new Thread(w);  //一个对象放到三个构造器中,相当于三个线程用的同一个对象,所以ticket不用担心是总数是300
       Thread t2 = new Thread(w);
       Thread t3 = new Thread(w);

       t1.setName("窗口一");
       t2.setName("窗口二");
       t3.setName("窗口三");

       t1.start();
       t2.start();
       t3.start();
    }
}
//创建一个实现了Runnable接口的类
class Window1 implements Runnable{
    private int ticket = 5;

    public void run(){

       while(true){
           show();
       }
    }
    //提取出要同步的方法
private synchronized void show() {  //同步监视器:this
    if (ticket > 0) {

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + ticket);
        ticket--;
    }
    }
}

结果

窗口一卖票,票号为:5
窗口一卖票,票号为:4
窗口一卖票,票号为:3
窗口一卖票,票号为:2
窗口一卖票,票号为:1

表现不明显

去掉sleep试试
package new1;


public class demo4 {
    public static void main(String[] args) {
       Window1 w = new Window1(); //此时只造了一个对象

       Thread t1 = new Thread(w);  //一个对象放到三个构造器中,相当于三个线程用的同一个对象,所以ticket不用担心是总数是300
       Thread t2 = new Thread(w);
       Thread t3 = new Thread(w);

       t1.setName("窗口一");
       t2.setName("窗口二");
       t3.setName("窗口三");

       t1.start();
       t2.start();
       t3.start();
    }
}
//创建一个实现了Runnable接口的类
class Window1 implements Runnable{
    private int ticket = 100;

    public void run(){

       while(true){
           show();
       }
    }
private synchronized void show() {
    if (ticket > 0) {



        System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + ticket);
        ticket--;
    }
    }
}

结果

窗口一卖票,票号为:100
窗口一卖票,票号为:99
窗口一卖票,票号为:98
窗口一卖票,票号为:97
窗口一卖票,票号为:96
窗口一卖票,票号为:95
窗口一卖票,票号为:94
窗口一卖票,票号为:93
窗口一卖票,票号为:92
窗口一卖票,票号为:91
窗口一卖票,票号为:90
窗口一卖票,票号为:89
窗口一卖票,票号为:88
窗口一卖票,票号为:87
窗口一卖票,票号为:86
窗口一卖票,票号为:85
窗口一卖票,票号为:84
窗口一卖票,票号为:83
窗口一卖票,票号为:82
窗口一卖票,票号为:81
窗口一卖票,票号为:80
窗口一卖票,票号为:79
窗口一卖票,票号为:78
窗口一卖票,票号为:77
窗口三卖票,票号为:76
窗口三卖票,票号为:75
窗口三卖票,票号为:74
窗口三卖票,票号为:73
窗口三卖票,票号为:72
窗口三卖票,票号为:71
窗口三卖票,票号为:70
窗口三卖票,票号为:69
窗口三卖票,票号为:68
窗口三卖票,票号为:67
窗口三卖票,票号为:66
窗口三卖票,票号为:65
窗口三卖票,票号为:64
窗口三卖票,票号为:63
窗口三卖票,票号为:62
窗口三卖票,票号为:61
窗口三卖票,票号为:60
窗口三卖票,票号为:59
窗口三卖票,票号为:58
窗口三卖票,票号为:57
窗口三卖票,票号为:56
窗口二卖票,票号为:55
窗口二卖票,票号为:54
窗口二卖票,票号为:53
窗口二卖票,票号为:52
窗口二卖票,票号为:51
窗口二卖票,票号为:50
窗口二卖票,票号为:49
窗口二卖票,票号为:48
窗口二卖票,票号为:47
窗口二卖票,票号为:46
窗口二卖票,票号为:45
窗口二卖票,票号为:44
窗口二卖票,票号为:43
窗口二卖票,票号为:42
窗口二卖票,票号为:41
窗口二卖票,票号为:40
窗口二卖票,票号为:39
窗口二卖票,票号为:38
窗口二卖票,票号为:37
窗口二卖票,票号为:36
窗口二卖票,票号为:35
窗口二卖票,票号为:34
窗口二卖票,票号为:33
窗口二卖票,票号为:32
窗口二卖票,票号为:31
窗口二卖票,票号为:30
窗口二卖票,票号为:29
窗口二卖票,票号为:28
窗口二卖票,票号为:27
窗口二卖票,票号为:26
窗口二卖票,票号为:25
窗口二卖票,票号为:24
窗口二卖票,票号为:23
窗口二卖票,票号为:22
窗口二卖票,票号为:21
窗口二卖票,票号为:20
窗口二卖票,票号为:19
窗口二卖票,票号为:18
窗口二卖票,票号为:17
窗口二卖票,票号为:16
窗口二卖票,票号为:15
窗口二卖票,票号为:14
窗口二卖票,票号为:13
窗口二卖票,票号为:12
窗口二卖票,票号为:11
窗口二卖票,票号为:10
窗口二卖票,票号为:9
窗口二卖票,票号为:8
窗口二卖票,票号为:7
窗口二卖票,票号为:6
窗口二卖票,票号为:5
窗口二卖票,票号为:4
窗口二卖票,票号为:3
窗口二卖票,票号为:2
窗口二卖票,票号为:1

当然因为同步方法,没有写break。需要手动停止进程

二·继承类

package new1;

public class demo3 {
    public static void main(String[] args) {
        window t1 = new window();
        window t2 = new window();
        window t3 = new window();

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }

}

class window extends Thread{
    private  static int ticket = 200;

    public void run() {

        while (true) {

            show();
        }
    }

private static synchronized void show(){  //加静态,防止同步方法失效(同步监视器window.class)
                if (ticket > 0) {
                    //加Thread.currentThread()使调用,因为getName()不是静态方法,show()无法调用
                    System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + ticket);
                    ticket--;
        }
    }
}

结果

窗口1卖票,票号为:200
窗口1卖票,票号为:199
窗口1卖票,票号为:198
窗口1卖票,票号为:197
窗口1卖票,票号为:196
窗口1卖票,票号为:195
窗口1卖票,票号为:194
窗口1卖票,票号为:193
窗口1卖票,票号为:192
窗口1卖票,票号为:191
窗口1卖票,票号为:190
窗口3卖票,票号为:189
窗口3卖票,票号为:188
窗口3卖票,票号为:187
窗口3卖票,票号为:186
窗口3卖票,票号为:185
窗口3卖票,票号为:184
窗口3卖票,票号为:183
窗口3卖票,票号为:182
窗口3卖票,票号为:181
窗口3卖票,票号为:180
窗口3卖票,票号为:179
窗口3卖票,票号为:178
窗口3卖票,票号为:177
窗口3卖票,票号为:176
窗口3卖票,票号为:175
窗口3卖票,票号为:174
窗口3卖票,票号为:173
窗口3卖票,票号为:172
窗口3卖票,票号为:171
窗口3卖票,票号为:170
窗口2卖票,票号为:169
窗口2卖票,票号为:168
窗口2卖票,票号为:167
窗口2卖票,票号为:166
窗口2卖票,票号为:165
窗口2卖票,票号为:164
窗口2卖票,票号为:163
窗口2卖票,票号为:162
窗口2卖票,票号为:161
窗口2卖票,票号为:160
窗口2卖票,票号为:159
窗口2卖票,票号为:158
窗口2卖票,票号为:157
窗口2卖票,票号为:156
窗口2卖票,票号为:155
窗口2卖票,票号为:154
窗口2卖票,票号为:153
窗口2卖票,票号为:152
窗口2卖票,票号为:151
窗口2卖票,票号为:150
窗口2卖票,票号为:149
窗口2卖票,票号为:148
窗口2卖票,票号为:147
窗口2卖票,票号为:146
窗口2卖票,票号为:145
窗口2卖票,票号为:144
窗口2卖票,票号为:143
窗口2卖票,票号为:142
窗口2卖票,票号为:141
窗口2卖票,票号为:140
窗口2卖票,票号为:139
窗口2卖票,票号为:138
窗口2卖票,票号为:137
窗口2卖票,票号为:136
窗口2卖票,票号为:135
窗口2卖票,票号为:134
窗口2卖票,票号为:133
窗口2卖票,票号为:132
窗口2卖票,票号为:131
窗口2卖票,票号为:130
窗口2卖票,票号为:129
窗口2卖票,票号为:128
窗口2卖票,票号为:127
窗口2卖票,票号为:126
窗口2卖票,票号为:125
窗口2卖票,票号为:124
窗口2卖票,票号为:123
窗口2卖票,票号为:122
窗口2卖票,票号为:121
窗口2卖票,票号为:120
窗口2卖票,票号为:119
窗口2卖票,票号为:118
窗口2卖票,票号为:117
窗口2卖票,票号为:116
窗口2卖票,票号为:115
窗口2卖票,票号为:114
窗口2卖票,票号为:113
窗口2卖票,票号为:112
窗口2卖票,票号为:111
窗口2卖票,票号为:110
窗口2卖票,票号为:109
窗口2卖票,票号为:108
窗口2卖票,票号为:107
窗口2卖票,票号为:106
窗口2卖票,票号为:105
窗口2卖票,票号为:104
窗口2卖票,票号为:103
窗口2卖票,票号为:102
窗口2卖票,票号为:101
窗口2卖票,票号为:100
窗口2卖票,票号为:99
窗口2卖票,票号为:98
窗口2卖票,票号为:97
窗口2卖票,票号为:96
窗口2卖票,票号为:95
窗口2卖票,票号为:94
窗口2卖票,票号为:93
窗口2卖票,票号为:92
窗口2卖票,票号为:91
窗口2卖票,票号为:90
窗口2卖票,票号为:89
窗口2卖票,票号为:88
窗口2卖票,票号为:87
窗口2卖票,票号为:86
窗口2卖票,票号为:85
窗口2卖票,票号为:84
窗口2卖票,票号为:83
窗口2卖票,票号为:82
窗口2卖票,票号为:81
窗口2卖票,票号为:80
窗口2卖票,票号为:79
窗口2卖票,票号为:78
窗口2卖票,票号为:77
窗口2卖票,票号为:76
窗口2卖票,票号为:75
窗口2卖票,票号为:74
窗口2卖票,票号为:73
窗口2卖票,票号为:72
窗口2卖票,票号为:71
窗口2卖票,票号为:70
窗口2卖票,票号为:69
窗口2卖票,票号为:68
窗口2卖票,票号为:67
窗口2卖票,票号为:66
窗口2卖票,票号为:65
窗口2卖票,票号为:64
窗口2卖票,票号为:63
窗口2卖票,票号为:62
窗口2卖票,票号为:61
窗口2卖票,票号为:60
窗口2卖票,票号为:59
窗口2卖票,票号为:58
窗口2卖票,票号为:57
窗口2卖票,票号为:56
窗口2卖票,票号为:55
窗口2卖票,票号为:54
窗口2卖票,票号为:53
窗口2卖票,票号为:52
窗口2卖票,票号为:51
窗口2卖票,票号为:50
窗口2卖票,票号为:49
窗口2卖票,票号为:48
窗口2卖票,票号为:47
窗口2卖票,票号为:46
窗口2卖票,票号为:45
窗口2卖票,票号为:44
窗口2卖票,票号为:43
窗口2卖票,票号为:42
窗口2卖票,票号为:41
窗口2卖票,票号为:40
窗口2卖票,票号为:39
窗口2卖票,票号为:38
窗口2卖票,票号为:37
窗口2卖票,票号为:36
窗口2卖票,票号为:35
窗口2卖票,票号为:34
窗口2卖票,票号为:33
窗口2卖票,票号为:32
窗口2卖票,票号为:31
窗口2卖票,票号为:30
窗口2卖票,票号为:29
窗口2卖票,票号为:28
窗口2卖票,票号为:27
窗口2卖票,票号为:26
窗口2卖票,票号为:25
窗口2卖票,票号为:24
窗口2卖票,票号为:23
窗口2卖票,票号为:22
窗口2卖票,票号为:21
窗口2卖票,票号为:20
窗口2卖票,票号为:19
窗口2卖票,票号为:18
窗口2卖票,票号为:17
窗口2卖票,票号为:16
窗口2卖票,票号为:15
窗口2卖票,票号为:14
窗口2卖票,票号为:13
窗口2卖票,票号为:12
窗口2卖票,票号为:11
窗口2卖票,票号为:10
窗口2卖票,票号为:9
窗口2卖票,票号为:8
窗口2卖票,票号为:7
窗口2卖票,票号为:6
窗口2卖票,票号为:5
窗口2卖票,票号为:4
窗口2卖票,票号为:3
窗口2卖票,票号为:2
窗口2卖票,票号为:1

进程已结束,退出代码-1

关于同步方法的总结
  1. 同步方法仍然涉及同步监视器,只不过不需要我i们显示声明
  2. 非静态的同步方法,同步监视器是:this
  3. 静态的同步方法,同步监视器是:当前类本身
重点理解:静态里的Thread.currentThread()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值