Didn’t I have a question in my notes on the 22nd? Why is there no desynchronization in the program I compiled? I sent it to csdn. Now I have basically solved this problem. The following is the forum’s reply. Record summary
Replyer: bluesmile979 (laughing) ( ) Reputation: 100 2003-01-22 21:08:00 Score: 0
Let me tell you my opinion. I think the biggest problem is multi-threading. After reading your The code seems to only have two lines. In the example, there should be more threads. If multiple threads compete for time slices, the chance of being interrupted is naturally much greater. Even if you add a loop, due to the computing speed of the machine, it is still not as obvious as the competition between multiple threads. I don’t know what you think.
Replyer: xm4014(forrest) ( ) Reputation: 100 2003-01-22 22:07:00 Score: 0
to bluesmile979 (laughing)
I have also thought about whether it is caused by too few threads, but I If both parameters in the Think in Java routine are set to 1 and run, then in the end it will be the same as the program I wrote, with only two threads, and the result will still be out of sync. How to explain this
Reply to person :tianfeichen (listen carefully) ( ) Reputation: 110 2003-01-22 23:57:00 Score: 0
The arrangement of threads is random after all, and it is rare for out-of-synchronization to occur. If the number is small, it is not easy to find.
My usual method is to start the infinite loop first, and do not require any output during the loop. I only add a stop condition, such as:
if (counter1 != counter2)
{
System.out.PRintln( counter1 + " ," + counter2)
System.exit(0);
}
All that's left is to wait. The results usually come out within ten seconds or even a few seconds. You can find that the count has reached hundreds of thousands or hundreds. All in all.
If 5 threads are opened at the same time and I wait for a minute, I will consider it to be synchronized.
My method may not be very scientific, but the effect is quite good.
Replyer: xm4014(forrest) ( ) Reputation: 100 2003-01-23 11:44:00 Score: 0
Can you help me debug it? Why do I never get results when I follow your method?
Just copy the following code directly. The program name is Sharing2.java and the version is 1.4.1
class TwoCounter extends Thread {
private int count1 = 0, count2 = 0;
private boolean started=false;
public void start(){
if (!started)
{
started=true;
super.start();
}
}
public void run() {
while (true) {
count1++;
count2++;
// System.out.println("Count1="+count1+",Count2="+count2);
try {
sleep(500);
} catch (InterruptedException e){System.out.println("TwoCounter.run") ;}
}
}
public void synchTest() {
// Sharing2.incrementaccess();
if(count1 != count2)
{System.out.println(count1+","+count2);
System. exit(0);
}
}
}
class Watcher extends Thread {
private Sharing2 p;
public Watcher(Sharing2 p) {
this.p = p;
start();
}
public void run( ) {
while(true) {
p.s.synchTest();
try {
sleep(500);
} catch (InterruptedException e){System.out.println("Watcher.run");}
}
}
}
public class Sharing2 {
TwoCounter s;
private static int accessCount = 0;
public static void incrementAccess() {
// accessCount++;
// System.out.println("accessCount="+accessCount);
}
public static void main(String[] args) {
Sharing2 aaa = new Sharing2();
aaa.s=new TwoCounter();
aaa.s.start();
new Watcher(aaa);
}
} ///:~
In addition, according to your point of view, there is no problem with my program, but there are fewer threads, and it is difficult to cause desynchronization. It is only possible when the counter increases to a large number, right? ?
Reply by: hey_you(Hey) ( ) Reputation: 100 2003-01-23 13:27:00 Score: 0
This is what I think: conflict due to lack of synchronization is a possibility, and sychronize allows This possibility is 0. Just because you didn't discover out-of-synchronization, you can't prove that out-of-synchronization will never happen. It's just a matter of time. The system's thread scheduling is affected by the environment. If there are many programs running on your machine at the same time, the situation may be different.
Replyer: xm4014(forrest) ( ) Reputation: 100 2003-01-23 15:56:00 Score: 0
Haha, I used the tianfeichen method to run the program, which is the code I posted above There are actually results, counter1=217327, counter2=217356, I really think they are quite different. But the time is by no means as simple as one or two minutes. It took at least two hours. It may be caused by the difference in my operating environment and his. As hey_you (Hey) said, it is just a matter of time.
I hope others can Give more opinions, if you think there is no need to discuss further, then I will accept the post.
Replyer: bluesmile979 (laughing) ( ) Reputation: 100 2003-01-23 16:38:00 Score: 0
I'll take the test. If you can persist for an hour or two, you'll be convinced.
I think the result of the problem is only two points. One is the number of threads I think
The other is what you think setText will do more processing and occupy more resources.
Both situations will affect the probability of this problem:) Let me sum it up, haha.
Replyer: linliangyi (Blue Mountain Coffee) ( ) Reputation: 100 2003-01-23 17:10:00 Score: 0
sleep (500) takes up more time than for (5000), so the thread is in sleep The probability of being switched in is far better than the probability of being interrupted in for! ! (You will know when you look back at my program)
In fact, the fact that the two variables changed from unequal to equal shows that they are out of sync! !
By the way, when swing and awt controls are operated in threads, such as setText, they often cause many accidents
The author can read related books! !
Replyant: xm4014(forrest) ( ) Reputation: 100 2003-01-24 14:25:00 Score: 0
I will sum up everyone’s opinions:
The first thing to be sure of is that if you do not use synchronized Keywords are used to define synchronization methods or synchronization blocks. Then, the possibility of desynchronization definitely exists. On the other hand, synchronized makes this possibility 0.
In the first case, desynchronization occurs. Although it may exist, its probability is affected by the following factors
1. Under different operating systems and operating environments, the probability of catching desynchronization may be different, or the waiting time may be different. Short
2. The number of threads in the program. If there are too few threads, then this kind of desynchronization will be difficult to catch, and you may need to wait for a long time
3. The impact of the code itself. For example, the use of GUI in the awt class Method may take up more resources and cause many accidents, so the possibility of conflicts is much greater
4. Threads are randomly allocated by the operating system, and there is inherent uncertainty. This uncertainty It will also affect the final result
I don’t know if it is correct. What else can you add?
The post will be officially closed tomorrow
But to be honest, I am a little confused about why the final results are counter1 (217327) and counter2 (217356) ) would be so different. According to my program, even if the watcher thread is inserted between two self-increasing statements, the difference between the two counters detected is at most 1. Such a big difference occurs. It can only be that the self-increment statement of a certain counter has been forcibly interrupted many times without running at all. This is too scary! Although the existence of other threads will interfere with the current thread, it will not let the current thread The statement is not running, right? The most I can do is wait and run it again? I'm a little confused. I haven't learned the operating system well. If you don't mind it, could you please explain it to me
As a result, there are new problems now, and I want to do it again. We won't have the answer until tomorrow
But we can solve another problem involving synchronized today. This is a post I saw on the forum. It is precisely because I can't solve it that I think it is necessary to go back and study it carefully Questions about threads and synchronization are as follows:
file://Analyze this program and explain it, focusing on synchronized, wait(), and notify. Thank you!
class ThreadA
{
public static void main(String[] args)
{
ThreadB b=new ThreadB();
b.start();
System.out.println("b is start...." );
synchronized(b)//What does b in brackets mean and what role does it play?
{
try
{
System.out.println("Waiting for b to complete...");
b.wait ();//What does this sentence mean, who should wait?
System.out.println("Completed.Now back to main thread");
}catch (InterruptedException e){}
}
System.out. println("Total is :"+b.total);
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this)
{
System.out.println ("ThreadB is running..");
for (int i=0;i<100;i++ )
{
total +=i;
System.out.println("total is "+total);
}
notify();
}
}
}
To analyze this program, you must first understand notify() and wait(). Why were these two methods not recorded when recording threads a few days ago? Because these two methods It does not originally belong to the Thread class, but belongs to the lowest basic object class. In other words, not only Thread, every object has the notify and wait functions. Why? Because they are used to manipulate locks, and every object has a lock. Locks are the basis of every object. Since locks are basic, of course the method of manipulating locks is also the most basic.
Before we read on, , first of all, it is best to review Part 3 of Think in Java 14.3.1: waiting and notification, that is, wait() and notify.
According to the explanation in Think in Java: "wait() allows us to thread Put into the "sleep" state, and at the same time "actively" wait for the conditions to change. And only when a notify() or notifyAll() changes, the thread will be awakened and check whether the conditions have changed."
Let's explain this sentence.
"wait() allows us to put the thread into the "sleep" state", that is to say, wait also blocks the current thread, which is the same as sleep or suspend. That is the same as sleep , what is the difference between suspend?
The difference is that "(wait) simultaneously "actively" waits for the conditions to change. This is very important. Sleep and suspend cannot do this. Because we sometimes need the help of synchronization to prevent conflicts between threads. Once synchronization is used, the object must be locked, that is, the object lock must be acquired. Other threads that want to use the object lock can only wait in line until all the programs in the synchronization method or synchronization block have run. In the synchronization method, In synchronized blocks, neither sleep() nor suspend() can unlock when they are called. They both occupy the object lock in use.
But wait can, it can make synchronized methods or synchronized blocks Temporarily give up the object lock and temporarily give it to other people who need the object lock (here it should be the program block, or the thread). This means that other synchronization methods in the thread object can be called during the execution of wait()! In other Under certain circumstances (sleep, suspend), this is impossible.
But pay attention to what I said earlier, I only temporarily give up the object lock and temporarily use it for other threads. The thread where I wait still needs to take back the object lock. Yeah. Wait what? Just wait and give it back to me after someone else has used it!
Okay, then how do you get the object lock back?
The first method is to limit the lending time. Set parameters in wait(), such as wait(1000), in milliseconds, which means I only lend out 1 In seconds, I will take it back automatically after one second. The second method is to ask the person who lent it to notify me that he has finished using it and wants to return it to me. At this time, I will take it back immediately. Hey, if I set I took it back after 1 hour, but others only took half an hour to finish it, so what should I do? Damn! Of course I took it back after using it, no matter how long I set it.
So how do others notify me? I believe it. Everyone can think of notify(), which is the meaning of the last sentence "And the thread will be awakened only when a notify() or notifyAll() changes."
Therefore, we can use a wait () and notify() are placed inside any synchronized method or synchronized block, regardless of whether thread-related processing is prepared in that class. And in fact, we can only call wait() and notify() in synchronized methods or synchronized blocks.
At this time, it is easy for us to explain the above program.
synchronized(b){... }; means to define a synchronization block and use b as a resource lock. b.wait(); means to temporarily release the lock and block the current thread so that other threads using the same lock have the opportunity to execute. The one who wants to use the same lock here is the b thread itself. This thread will not be executed until a certain point. After that, use notify() to notify the thread of wait that the lock has been used up. After the synchronization block where notify() is located has finished running, the thread where wait is located can continue to execute.