线程的安全问题的解决方法-同步方法
作者:互联网
同步方法
如果操作共享数据的代码完整的声明在一个方法中,我们可以将此方法声明同步的
一·实现类:
将要同步的方法单独挑选出来
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
关于同步方法的总结
- 同步方法仍然涉及同步监视器,只不过不需要我i们显示声明
- 非静态的同步方法,同步监视器是:this
- 静态的同步方法,同步监视器是:当前类本身
重点理解:静态里的Thread.currentThread()
标签:同步,窗口,Thread,卖票,票号,线程,new,ticket,方法 来源: https://blog.csdn.net/weixin_48063660/article/details/113805952