`
zhaohaolin
  • 浏览: 1011155 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Object中的同步机制[转]

    博客分类:
  • JAVA
阅读更多

Object中的同步机制

 
附件
robot.JPG(20.0 K)
 
切换到幻灯片模式

程序不是玩具,必须具备商业运作的稳定性。所以在运行的时候要充分考虑不同线程之间的同步性。在使用同步性技术的时候,考虑到标志布尔型变量与while循环搭配的效果容易对CPU造成很大的资源浪费,所以在这里采取了wait+notify技术。 
Java在设计之初就充分考虑到了线程同步的问题,因而在设计基础类Oject的时候就为其提供了基于同步技术的三个函数wait+notify+notifyAll。这就意味着你所编写的任何类都可以使用这些方法(虽然在某些时候这些方法是根本没有意义的)。 
我们知道,Thread对象的sleep()方法也可以使当前线程暂停运行。但sleep()方法和wait()方法从本质上来说是不一样的。sleep()使得一个进程进入睡眠状态,但其线程所占有的资源并没有释放。假设,你在synchronized模块(加函数锁或者对象锁)里调用了sleep(),虽然线程睡着了而且没有使用资源,但是它依然保存着锁,别的线程依然无法调用相关的synchronized模块。而wait()则不同,它实际上了是放弃了锁,将资源贡献出来,而使自己暂时离岗。这个离岗状态一直会持续到“boss”(其他的线程)调用了notify(),通知线程继续回来工作为止。 
关于线程同步的三个函数,JAVA DOC中是这样描述的: 
wait导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行. 
notify唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。此方法只应由作为此对象监视器的所有者的线程来调用. 
"当前的线程必须拥有此对象监视器"与"此方法只应由作为此对象监视器的所有者的线程来调用"说明wait方法与notify方法必须在同步块内执行,即synchronized(obj之内). 
调用对像wait方法后,当前线程释放对像锁,进入等待状态.直到其他线程(也只能是其他线程)通过notify 方法,或 notifyAll.该线程重新获得对像锁. 
继续执行,记得线程必须重新获得对像锁才能继续执行.因为synchronized代码块内没有锁是寸步不能走的. 
下面我举一个实际例子来说明线程的同步问题: 
例子非常通俗易懂。我将构造一个机器人。该机器人有一个身子,两只胳膊和两条腿。除了身子不动外,头、腿和胳膊要有节律地运动。因为每个零件的运动都在单独的一个线程内,所以要想让胳膊和腿按照一定的顺序执行,必须使用同步机制。 
首先来看一个无规律运动的实例代码: 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
package ql.abs;
 
import java.io.*;
import java.text.*;
import java.util.*;
import java.net.*;
import quanwen.*;    //常用函数
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.border.*;
import java.util.Iterator;
import java.util.List;
 
/**
 * 一个未基于线程同步的小机器人
 */
public class ExpNoSync extends JFrame{
  JPanel pnlTop=new JPanel(),
         pnlBottom=new JPanel();
 
  JPanel pnlTopLeft=new JPanel(),
         pnlTopRight=new JPanel(),
         pnlTopCenter=new JPanel();
 
  JPanel armLeft=new Arm1(),
         pnlTopLeft2=new JPanel();
 
  JPanel armRight=new Arm2(),
         pnlTopRight2=new JPanel();
 
  JPanel pnlBottomLeft=new JPanel(),
         leg=new Leg(),
         pnlBottomRight=new JPanel();
 
  JPanel head=new Head();
 
  Container c;
 
 
  public ExpNoSync(){
    super("小机器人");
    armLeft.setPreferredSize(new Dimension(50,50));
    pnlTopLeft2.setPreferredSize(new Dimension(50,50));
 
    pnlTopCenter.setBackground(Color.white);
    pnlTopCenter.setPreferredSize(new Dimension(50,50));
    
 
    armRight.setPreferredSize(new Dimension(50,50));
    pnlTopRight2.setPreferredSize(new Dimension(50,50));
 
 
 
    pnlBottomLeft.setPreferredSize(new Dimension(50,50));
    leg.setPreferredSize(new Dimension(50,50));
    pnlBottomRight.setPreferredSize(new Dimension(50,50));
 
 
    c=getContentPane();
    c.setLayout(new GridLayout(3,3,0,0));
    c.add(pnlBottomLeft);
    c.add(head);
    c.add(pnlBottomRight);
    c.add(armLeft);
    c.add(pnlTopCenter);
    c.add(armRight);
    c.add(pnlTopRight2);
    c.add(leg);
    c.add(pnlTopRight);
 
    setSize(167,160);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    show(); 
  }
  public static void main(String[] args){
    ExpNoSync exp=new ExpNoSync();
  }
  class Arm1 extends JPanel{
     ImageIcon[] icon=new ImageIcon[2];
     int step=0;
     JLabel lblArm1=new JLabel();
     Runnable changeIt=new Runnable(){
       public void run(){
         lblArm1.setIcon(icon[step]);
       }
     };
     Thread t=new Thread(){
       public void run(){
         //休眠1秒钟
         while(true){
           try{
             this.sleep(500);
           }catch(Exception ex){return;}
 
           SwingUtilities.invokeLater(changeIt);              
 
           step++;
           if(step>1) step=0;
         }
       }
     };
     public Arm1(){
       icon[0]=new ImageIcon(Arm1.class.getResource("image/armLeft1.GIF"));
       icon[1]=new ImageIcon(Arm1.class.getResource("image/armLeft2.GIF"));
 
       setLayout(new FlowLayout(FlowLayout.RIGHT));
       lblArm1.setIcon(icon[step]);
       add(lblArm1);
       t.start();
     }
 
     public Dimension getPreferredSize(){
       return new Dimension(50,50);
     }
  }
  class Arm2 extends JPanel{
     ImageIcon[] icon=new ImageIcon[2];
     int step=0;
     JLabel lblArm2=new JLabel();
     Runnable changeIt=new Runnable(){
       public void run(){
         lblArm2.setIcon(icon[step]);
       }
     };
     Thread t=new Thread(){
       public void run(){
         //休眠1秒钟
         while(true){
           try{
             this.sleep(500);
           }catch(Exception ex){return;}
 
           SwingUtilities.invokeLater(changeIt);              
 
           step++;
           if(step>1) step=0;
         }
       }
     };
 
     public Arm2(){
       icon[0]=new ImageIcon(Arm2.class.getResource("image/armRight1.GIF"));
       icon[1]=new ImageIcon(Arm2.class.getResource("image/armRight2.GIF"));
 
       setLayout(new FlowLayout(FlowLayout.RIGHT));
       lblArm2.setIcon(icon[step]);
       add(lblArm2);
       t.start();
     }
     public Dimension getPreferredSize(){
       return new Dimension(50,50);
     }
  }
  class Leg extends JPanel{
     ImageIcon[] icon=new ImageIcon[2];
     int step=0;
     JLabel lblLeg=new JLabel();
     Runnable changeIt=new Runnable(){
       public void run(){
         lblLeg.setIcon(icon[step]);
       }
     };
     Thread t=new Thread(){
       public void run(){
         //休眠1秒钟
         while(true){
           try{
             this.sleep(500);
           }catch(Exception ex){return;}
 
           SwingUtilities.invokeLater(changeIt);              
 
           step++;
           if(step>1) step=0;
         }
       }
     };
 
     public Leg(){
       icon[0]=new ImageIcon(Leg.class.getResource("image/leg1.GIF"));
       icon[1]=new ImageIcon(Leg.class.getResource("image/leg2.GIF"));
 
       setLayout(new FlowLayout(FlowLayout.RIGHT));
       lblLeg.setIcon(icon[step]);
       add(lblLeg);
       t.start();
     }
     public Dimension getPreferredSize(){
       return new Dimension(50,50);
     }
  }
  class Head extends JPanel{
     ImageIcon[] icon=new ImageIcon[2];
     int step=0;
     JLabel lblHead=new JLabel();
     Runnable changeIt=new Runnable(){
       public void run(){
         lblHead.setIcon(icon[step]);
       }
     };
     Thread t=new Thread(){
       public void run(){
         //休眠1秒钟
         while(true){
           try{
             this.sleep(500);
           }catch(Exception ex){return;}
 
           SwingUtilities.invokeLater(changeIt);              
 
           step++;
           if(step>1) step=0;
         }
       }
     };
 
     public Head(){
       icon[0]=new ImageIcon(Head.class.getResource("image/head1.GIF"));
       icon[1]=new ImageIcon(Head.class.getResource("image/head2.GIF"));
 
       setLayout(new FlowLayout(FlowLayout.RIGHT));
       lblHead.setIcon(icon[step]);
       add(lblHead);
       t.start();
     }
     public Dimension getPreferredSize(){
       return new Dimension(50,50);
     }
  }
 
}


瞬间捕捉的图形如下: 



从运行效果上看,因为眼睛、手、脚都没有使用同步机制,所以其运动是没有规律的。现在我们为它加上同步机制,要求按照先动眼睛,再动左手,再动右手,最后动脚的顺序循环播放,更改后的代码如下: 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
package ql.abs;
 
import java.io.*;
import java.text.*;
import java.util.*;
import java.net.*;
import quanwen.*;    //常用函数
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.border.*;
import java.util.Iterator;
import java.util.List;
 
/**
 * 一个基于线程同步的机器人
 */
public class ExpSync extends JFrame{
  Object headLock = new Object();
  Object arm1Lock = new Object();
  Object arm2Lock = new Object();
  Object legLock = new Object();
 
  JPanel pnlTop=new JPanel(),
         pnlBottom=new JPanel();
 
  JPanel pnlTopLeft=new JPanel(),
         pnlTopRight=new JPanel(),
         pnlTopCenter=new JPanel();
 
  JPanel armLeft=new Arm1(),
         pnlTopLeft2=new JPanel();
 
  JPanel armRight=new Arm2(),
         pnlTopRight2=new JPanel();
 
  JPanel pnlBottomLeft=new JPanel(),
         leg=new Leg(),
         pnlBottomRight=new JPanel();
 
  JPanel head=new Head();
 
 
  Container c;
 
 
  public ExpSync(){
    super("小机器人");
    armLeft.setPreferredSize(new Dimension(50,50));
    pnlTopLeft2.setPreferredSize(new Dimension(50,50));
 
    pnlTopCenter.setBackground(Color.white);
    pnlTopCenter.setPreferredSize(new Dimension(50,50));
    
 
    armRight.setPreferredSize(new Dimension(50,50));
    pnlTopRight2.setPreferredSize(new Dimension(50,50));
 
 
 
    pnlBottomLeft.setPreferredSize(new Dimension(50,50));
    leg.setPreferredSize(new Dimension(50,50));
    pnlBottomRight.setPreferredSize(new Dimension(50,50));
 
 
    c=getContentPane();
    c.setLayout(new GridLayout(3,3,0,0));
    c.add(pnlBottomLeft);
    c.add(head);
    c.add(pnlBottomRight);
    c.add(armLeft);
    c.add(pnlTopCenter);
    c.add(armRight);
    c.add(pnlTopRight2);
    c.add(leg);
    c.add(pnlTopRight);
 
    setSize(167,160);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    show(); 
    //每隔4秒为arm1线程解锁一次
    Arm1Released ar=new Arm1Released();
    ar.start();
  }
  public static void main(String[] args){
    ExpSync exp=new ExpSync();
  }
  //为线程锁链中的左边胳膊解锁
  class Arm1Released extends Thread{
    public void run(){
      while(true){
        try{
          this.sleep(4000);
        }catch(Exception ex){}          
        
        //为arm1解锁
        synchronized(arm1Lock) {
          arm1Lock.notify();
        }                   
        System.out.println("--- Send arm1Lock notify...");       
      }
    }
  }
 
  //左边的胳膊
  class Arm1 extends JPanel{
     ImageIcon[] icon=new ImageIcon[2];
     int step=0;
     JLabel lblArm1=new JLabel();
     Runnable changeIt=new Runnable(){
       public void run(){
         lblArm1.setIcon(icon[step]);
       }
     };
     Thread t=new Thread(){
       public void run(){
         //休眠1秒钟
         while(true){
           System.out.println("arm1 is locked");
           //arm1等待head来解锁
           synchronized (arm1Lock) {
             try {
                arm1Lock.wait();
             } catch (InterruptedException ie) {
                System.out.println(ie.toString());
             }
           }
           System.out.println("arm1 is released");  
 
           SwingUtilities.invokeLater(changeIt);    
 
           try{
             Thread.currentThread().sleep(1000);
           }catch(Exception ex){}          
 
           //arm1为arm2解锁
           synchronized(arm2Lock) {
             arm2Lock.notify();
           }
           System.out.println("--- Send arm2Lock notify...");     
 
 
           step++;
           if(step>1) step=0;
          
         }
       }
     };
     public Arm1(){
       icon[0]=new ImageIcon(Arm1.class.getResource("image/armLeft1.GIF"));
       icon[1]=new ImageIcon(Arm1.class.getResource("image/armLeft2.GIF"));
 
       setLayout(new FlowLayout(FlowLayout.RIGHT));
       lblArm1.setIcon(icon[step]);
       add(lblArm1);
       t.start();
     }
 
     public Dimension getPreferredSize(){
       return new Dimension(50,50);
     }
  }
  class Arm2 extends JPanel{
     ImageIcon[] icon=new ImageIcon[2];
     int step=0;
     JLabel lblArm2=new JLabel();
     Runnable changeIt=new Runnable(){
       public void run(){
         lblArm2.setIcon(icon[step]);
       }
     };
     Thread t=new Thread(){
       public void run(){
         //休眠1秒钟
         while(true){
           System.out.println("arm2 is locked");
           //arm2等待arm1来解锁
           synchronized (arm2Lock) {
             try {
                arm2Lock.wait();
             } catch (InterruptedException ie) {}
           }
           System.out.println("arm2 is released");          
 
           SwingUtilities.invokeLater(changeIt);    
 
           try{
             Thread.currentThread().sleep(1000);
           }catch(Exception ex){}          
 
           //arm2为leg解锁
           synchronized(legLock) {
             legLock.notify();
           }           
           System.out.println("--- Send legLock notify...");       
 
           step++;
           if(step>1) step=0;
         }
       }
     };
 
     public Arm2(){
       icon[0]=new ImageIcon(Arm2.class.getResource("image/armRight1.GIF"));
       icon[1]=new ImageIcon(Arm2.class.getResource("image/armRight2.GIF"));
 
       setLayout(new FlowLayout(FlowLayout.RIGHT));
       lblArm2.setIcon(icon[step]);
       add(lblArm2);
       t.start();
     }
     public Dimension getPreferredSize(){
       return new Dimension(50,50);
     }
  }
  class Leg extends JPanel{
     ImageIcon[] icon=new ImageIcon[2];
     int step=0;
     JLabel lblLeg=new JLabel();
     Runnable changeIt=new Runnable(){
       public void run(){
         lblLeg.setIcon(icon[step]);
       }
     };
     Thread t=new Thread(){
       public void run(){
         //休眠1秒钟
         while(true){
           System.out.println("leg is locked");
           //leg等待arm2来解锁
           synchronized (legLock) {
             try {
                legLock.wait();
             } catch (InterruptedException ie) {}
           }
           System.out.println("leg is released");          
 
           SwingUtilities.invokeLater(changeIt);   
 
           try{
             Thread.currentThread().sleep(1000);
           }catch(Exception ex){}          
 
           //leg为head解锁
           synchronized(headLock) {
             headLock.notify();
           }       
           System.out.println("--- Send headLock notify...");       
   
           step++;
           if(step>1) step=0;
         }
       }
     };
 
     public Leg(){
       icon[0]=new ImageIcon(Leg.class.getResource("image/leg1.GIF"));
       icon[1]=new ImageIcon(Leg.class.getResource("image/leg2.GIF"));
 
       setLayout(new FlowLayout(FlowLayout.RIGHT));
       lblLeg.setIcon(icon[step]);
       add(lblLeg);
       t.start();
     }
     public Dimension getPreferredSize(){
       return new Dimension(50,50);
     }
  }
  class Head extends JPanel{
     ImageIcon[] icon=new ImageIcon[2];
     int step=0;
     JLabel lblHead=new JLabel();
     Runnable changeIt=new Runnable(){
       public void run(){
         lblHead.setIcon(icon[step]);
       }
     };
     Thread t=new Thread(){
       public void run(){
         while(true){
           System.out.println("head is locked");
           //head等待leg来解锁
           synchronized (headLock) {
             try {
                headLock.wait();
             } catch (InterruptedException ie) {}
           }
           System.out.println("head is released");            
 
           SwingUtilities.invokeLater(changeIt);  
 
           try{
             Thread.currentThread().sleep(1000);
           }catch(Exception ex){}          
 
           //head为arm1解锁
           synchronized(arm1Lock) {
             arm1Lock.notify();
           }                   
           System.out.println("--- Send arm1Lock notify...");       
 
           step++;
           if(step>1) step=0;
         }
       }
     };
 
     public Head(){
       icon[0]=new ImageIcon(Head.class.getResource("image/head1.GIF"));
       icon[1]=new ImageIcon(Head.class.getResource("image/head2.GIF"));
 
       setLayout(new FlowLayout(FlowLayout.RIGHT));
       lblHead.setIcon(icon[step]);
       add(lblHead);
       t.start();
     }
     public Dimension getPreferredSize(){
       return new Dimension(50,50);
     }
  }
 
}
 


从代码可以看出。左胳膊Arm1先是阻塞自己,等待Arm1Released线程或Head线程释放自己,当自己被释放以后,则释放Arm2。右胳膊Arm2先是阻塞自己,等待Arm1线程释放自己,当自己被释放以后,则释放leg。腿Leg先是阻塞自己,等待Arm2线程释放自己,当自己被释放以后,则释放head。头Head先是阻塞自己,等待Leg线程释放自己,当自己被释放以后,则释放Arm1。 
因为左胳膊,右胳膊,腿,头三个线程之间不存在先后执行的问题,所以你在实际运行中会看到以下的顺序: 

arm1 is locked 
arm2 is locked 
leg is locked 
head is locked 
--- Send arm1Lock notify --- 1、 Arm1Released线程释放Arm1 
arm1 is released 2、 arm1被Arm1Released释放 
--- Send arm2Lock notify... 3、 arm1释放arm2 
arm1 is locked 
arm2 is released 4、 arm2被arm1释放 
--- Send legLock notify... 5、 arm2释放leg 
arm2 is locked 
leg is released 6、 leg被arm2释放 
--- Send headLock notify... 7、 leg释放head 
leg is locked 
head is released 8、head被leg释放 
--- Send arm1Lock notify... 9、head释放arm1 
head is locked 
arm1 is released 10、arm1被head释放 
--- Send arm1Lock notify --- 11、Arm1Released线程释放Arm1 
--- Send arm2Lock notify... 12、arm1释放arm2 
arm1 is locked 
arm2 is released 13、…… 
--- Send legLock notify... 
arm2 is locked 

程序开始运行构造函数中几个机器人的部件都被初始化,四个部件均被自己阻塞,如果Arm1Released不运行,则四个线程都无法继续工作。即无法执行释放别人的操作而造成整个程序死锁。 
分享到:
评论

相关推荐

    剖析MFC多线程程序的同步机制

    ### 剖析MFC多线程程序的同步机制 #### 概述 在现代软件开发中,多线程编程已成为提升程序性能的关键技术之一。然而,随着线程数量的增加,线程间的同步问题变得日益突出。MFC(Microsoft Foundation Classes)...

    Monitor-Object设计模式入手-探索Java同步机制-二.ppt

    在Monitor Object设计模式中,参与者之间将发生如下的协作过程:同步方法的调用和串行化、同步方法线程挂起、监视条件通知和同步方法线程恢复。在这种模式中,客户线程调用监视者对象的同步方法时,必须首先获取它的...

    java的线程同步机制synchronized关键字的理解_.docx

    Java 线程同步机制中 synchronized 关键字的理解 Java 的线程同步机制是为了解决多个线程共享同一片存储空间所带来的访问冲突问题。其中,synchronized 关键字是 Java 语言中解决这种冲突的重要机制。 ...

    Java异步调用转同步方法实例详解

    wait和notify方法是Java中最基本的同步机制,通过使用锁机制来实现异步调用转同步。下面是一个使用wait和notify方法的示例代码: ```java public class Demo1 extends BaseDemo { private final Object lock = ...

    Java分布式应用学习笔记03JVM对线程的资源同步和交互机制

    在深入探讨Java虚拟机(JVM)如何处理线程间的资源同步与交互机制之前,我们先来明确几个关键概念:线程、多线程、同步、并发以及它们在Java中的实现方式。Java作为一种广泛应用于分布式系统开发的编程语言,其内部...

    Java多线程同步机制在售票系统的实现

    4. **临界区**:临界区是指程序中可能被多个线程同时访问的关键代码区域,需要通过同步机制进行保护。 5. **同步机制**:Java通过`synchronized`关键字支持线程同步,包括同步块和同步方法。 #### 三、多线程同步...

    2 线程同步机制.md,学习代码

    标题中的“2 线程同步机制.md”可能涵盖了这些内容: 1. **synchronized 关键字**:Java中的`synchronized`关键字用于保证同一时间只有一个线程可以执行特定的代码块或方法,确保线程安全。它可以修饰实例方法、...

    同步代码块(synchronized).zip

    在Java编程语言中,同步代码块(synchronized blocks)是一种重要的多线程控制机制,用于保证线程安全,防止数据的不一致性。本压缩包包含了两个示例代码——Example12.java和Example13.java,它们是针对同步代码块...

    ActiveObject

    这通常涉及到线程安全的数据结构和同步机制。 3. **代理(Proxy)**:客户端通过代理对象与活性对象进行交互。代理负责将方法调用转换为任务并提交到任务队列,同时提供同步原语(如future或promise)以处理结果的...

    用C# MapObject编写的一个GIS程序

    在本文中,我们将深入探讨如何使用C#编程语言与Esri的MapObject库结合,来构建一个GIS(地理信息系统)程序。MapObject是Esri公司提供的一个强大的地图开发组件,它允许开发者创建交互式地图应用,支持多种地理数据...

    objectbox-examples,新的移动数据库objectbox的示例.zip

    - **实时数据同步**:ObjectBox支持实时数据监听,当数据库中的数据发生变化时,能够立即通知到应用程序,用于实现动态UI更新。 7. **缓存与性能**: - **内存缓存**:ObjectBox有内置的内存缓存机制,能快速访问...

    基于同步机制解决Java多线程安全问题的应用 (1).zip

    本主题将深入探讨如何利用同步机制来确保在Java环境中多线程操作的正确性和一致性。 一、线程安全问题 在多线程环境下,当多个线程访问共享资源时,如果没有适当的控制,可能会导致数据不一致、死锁、活锁或饥饿等...

    java 中ThreadLocal本地线程和同步机制的比较

    ThreadLocal不是一种同步机制,而是设计来解决线程间数据隔离问题的工具。 ThreadLocal接口提供三个主要方法:`get()`、`initialValue()` 和 `set(Object value)`。`get()` 方法返回当前线程的ThreadLocal变量副本...

    数据库同步过程中如何解决大字段的同步

    在数据库管理中,大字段通常指的是那些存储大量数据的字段,如BLOB(Binary Large Object)、TEXT、VARCHAR(MAX)等类型。这些字段在处理时可能会带来性能问题,尤其是在同步过程中。本文将深入探讨大字段的使用场景...

    MapObject2.3 的 vc代码 common 文件

    9. **多线程支持**:如果MapObject支持多线程应用,"common"文件夹中可能会有线程安全的代码和同步原语,以确保在并发环境下的正确性。 10. **配置和设置**:通用配置文件或设置管理代码可能在这里,用于保存和读取...

    详解Java中Object 类的使用.rar

    6. **反射机制**:Object类中的`getClass()`方法返回一个`Class`对象,代表了运行时的类信息。配合Java的反射API,我们可以动态地获取类的属性、方法等信息,实现动态调用和类型检查。 7. **线程同步**:`wait()`、...

    《Object-Oriented Programming with Object C》 英文高清原版 PDF

    2. **Objective-C语言特性**:Objective-C是在C语言的基础上扩展的,保留了C的语法结构,同时添加了消息传递机制、类和其他面向对象的特性。消息传递是Objective-C的关键,通过`[receiver message]`的方式调用方法。...

    Object—C 开发包

    Object-C中的核心机制是消息传递。当你调用一个对象的方法时,实际上是在向对象发送一条消息。例如,`[myObject doSomething]`就是向`myObject`发送`doSomething`消息。这种设计使得代码具有很高的灵活性。 ### 3. ...

Global site tag (gtag.js) - Google Analytics