One. Understand interruptions.

So far I’m using threads: The first is to handle time-consuming operations. The second is in the background loop to do something for us. How do threads interrupt when loops are used to do something?

Everyone knows that a thread terminates when its run method runs out or when an exception occurs in the run method and is not caught. Jva originally provided a stop method to interrupt threads, but this method has since been abandoned. Instead, it provides an interrupt method to interrupt threads. Sounds hopeful, but the results are often disappointing. Let’s start with an interrupt method to interrupt a thread.

  • interrupt

    There is a default interrupt flag bit in the thread. The default value is FASle, and the thread will often access this flag bit when running again. To determine whether the thread will be terminated. We can call thread.currentThread ().isinterrupt () to get this bit. As follows:

     int i =0;
                while(! Thread.currentThread().isInterrupted()){ i++; Log.e("CHAO"."Thread 1 ->"+i);
                }Copy the code

You can also call Thread.interrupted() to reset the interrupt identifier bit. The interrupt() method can be called to interrupt a thread when an interrupt is needed.

 Thread.currentThread().interrupt();Copy the code

It’s worth mentioning here that when a thread is active, it doesn’t have to terminate when it calls this method. It interrupts only to get the thread’s attention, and the thread makes its own decision to respond to the interrupt. Some important threads will ignore the interrupt. Calling interrupt() when a thread is blocked or asleep throws InterruptedException and sets the interrupt identifier bit to FasLE. This is important and can be used to terminate a blocked thread. The other thing is to try not to catch an exception without doing anything. Usually we will print the exception information on the command line about where and why the exception went wrong in the program, i.e. E.printstacktrace (). We can design a reasonable way to interrupt a blocked thread or a sleeping thread.

   try {
                //  Thread.sleep(2000);
                int i =0;
                while (! Thread.currentThread().isInterrupted()){
                    i++;
                    Log.e("CHAO"."Thread 1 ->"+i);
                }
              } catch (Exception e) {
                  Log.e("CHAO"."Thread 1 Exception ->"+e); Thread.currentThread().interrupt(); e.printStackTrace(); } is not interrupted when won't cause abnormal. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = / / simulation interrupt threads blocked or sleep in the try {  int i =0; // Notice the loop judgment flag herewhile (! Thread.currentThread().isInterrupted()) {
                            i++;
                            Thread.sleep(2000);
                            Log.e("CHAO"."Thread 2 performs interrupt thread 1============================" +  i);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        Log.e("CHAO"."InterruptedException ->"+""); // Because the interrupt flag bit is set to fasle by default when an exception occurs, you need to call the interrupt once. Thread.currentthread ().interrupt(); }Copy the code
  • Since using an interrupt method doesn’t work the way we interrupt a thread, you’ve probably seen it before
Example 1: // Set onewhileThe end of the loop is marked with. Boolean tage =true;

        new Thread(){
            @Override
            public void run() {
                super.run();
                while (tage){
                 //do someThing
                }

            }
        }.start();Copy the code

This interrupts the thread by changing the value of the loop’s marker bit to allow the run method to finish. But this is 100% ok in a single thread, it’s not 100% ok in a multi-thread, it’s usually ok. Let’s look at some of the reasons for this indiscreet interruption: First, let’s take a look at Java’s memory model. The main goal of the Java memory model is to define the access rules for variables in the program, which is to get the low-level details involved in the storage of variables in the virtual machine. More special is Shared variables (in this case, the variable is Shared variables). The Java memory model of variables are stored in main memory, and each thread has its own memory, working memory is saved in the thread to the variables used in the main memory copy of a copy of the thread multivariable all the operations (read, write) have to work again Storage, can not directly read and write variables in memory. Threads cannot access the contents of the working memory, and variables are passed between threads through main memory. There is a special treatment for the Volatile keyword. Variables modified by the Volatile key can still share a copy of main memory, but because of the order of operations, data from main memory must be synchronized to working memory before being read or written from working memory. All look like read and write accesses directly in main memory, so the description here is no exception for volatile.

Okay, we’ll look at examples of case 1 interrupt threads, change the interrupt is marked as different variables, all of his, speaking, reading and writing are to follow the Java virtual machine specification, namely when there are other thread change tage is worth all the time need to change the value to write in the memory, other threads can get value after the change from main memory. However, an error can occur if the thread fails to write the value to main memory after modifying tage, which is rare but possible. To avoid this particular bug, consider the magic of the Volatile keyword. Let’s take a look at the implementation code:

Private volatile Boolean mInterrupt = private volatile Boolean mInterrupt =false;
 mInterrupt = true;
        thread1= new Thread(){
          @Override
          public void run() {
              super.run();
                int i =0;
                while (mInterrupt){
                    i++;
                    Log.e("CHAO"."Thread 1 ->"+i); }}}; thread1.start(); / / here interrupt threads The button in the main thread. SetOnClickListener (newOnClickListener() {
            @Override
            public void onClick(View v) {
                mInterrupt = false; }}); / / run results, here because the thread run really, really fast, so there will be delay. Click on the button when 10-24 22:18:44. 851, 3180-3602 / com. Example. Chao. Threaddemo E/chao: Thread 1 - > 10 119770-24 22:18:44. 851, 3180-3602 / com. Example. Chao. Threaddemo E/chao: Thread 1 - > 10 119771-24 22:18:44. 851, 3180-3602 / com. Example. Chao. Threaddemo E/chao: Thread 1 - > 10 119772-24 22:18:44. 851, 3180-3602 / com. Example. Chao. Threaddemo E/chao: Thread 1 - > 10 119773-24 22:18:44. 852, 3180-3602 / com. Example. Chao. Threaddemo E/chao: Thread 1 - > 10 119774-24 22:18:44. 852, 3180-3602 / com. Example. Chao. Threaddemo E/chao: Thread 1 - > 10 119775-24 22:18:44. 857, 3180-3602 / com. Example. Chao. Threaddemo E/chao: Thread 1 - > 10 120125-24 22:18:46. 968, 3180-3180 / com. Example. Chao. Threaddemo E/chao: interrupt ->==============================================Copy the code

1. Two meanings of Volatile

Once a shared variable (a member variable of a class, a static member variable of a class) is volatile, there are two layers of semantics.

  • This ensures visibility when different threads operate on the variable, i.e. when one thread changes the value of a variable, the new value is immediately visible to other threads. That is, when a volatile variable is changed and then changed, it will reflect the value directly into memory, independent of the current thread, and then invalidate the variable in the worker thread of all threads.
  • Command reordering is disabled. To recap, ordinary variables only guarantee that the correct result will be obtained wherever the assignment depends on the execution of the method, and there is no guarantee that the assignment will be performed in the same order as the execution in the program, which is not sensed in a single thread. The Java language specification specifies that SEQUENTIAL semantics are maintained within JVM threads, which means that instructions can be executed in a different order from code as long as the end result of a program is the same as it would be in a strictly sequential environment, through a process called reordering instructions. The significance of instruction reordering lies in that JVM can reorder machine instructions appropriately according to the characteristics of the processor (CPU’s multi-level cache system, multi-core processor, etc.), so that the machine instructions can be more consistent with the execution characteristics of THE CPU and maximize the performance of the machine. In the absence of synchronization, the compiler, processor, runtime, and so on can make unexpected adjustments to the order in which operations are executed.

Two end

Hopefully, this will give you a little perspective on interrupts and volatile. In the case of volatile, this is just a cursory look at why it can be used as a shared resource for threads. The internal principles are further involved. Tomorrow we’ll talk about the Java memory model.

Welcome everyone to ridicule, if you like, remember to like oh ~ tomorrow’s preview: Talk about Java memory model. Look forward to your attention