Example 1 – synchronized and volatile


package volatileTest;

public class VolatileTest01 {
    volatile 
	int i;

    // synchronized if commented out, sum will not equal to 1000
    // synchronized comments synchronized, even if volatile does not get 1000
    public void  addI(a){
        i++;
    }

    public static void main(String[] args) throws InterruptedException {
        final  VolatileTest01 test01 = new VolatileTest01();
        for (int n = 0; n < 1000; n++) {
            new Thread(new Runnable() {
                @Override
                public void run(a) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    test01.addI();
                }
            }).start();
        }

        Thread.sleep(10000);// Wait 10 seconds for the above program to completeSystem.out.println(test01.i); }}Copy the code

Cache Consistency Protocol – Intel’s MESI protocol ensures that copies of shared variables used in each cache are consistent. Its core idea is: When a CPU writes data, if it finds that the variable is a shared variable, that is, a copy of the variable exists in other cpus, it sends a signal to inform other cpus to set the cache line of the variable to invalid state. Therefore, when other cpus need to read the variable, they find that the cache line of the variable is invalid. Then it will re-read from memory.

Case 2 – CountDownLatch

package threadTest2;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolTest {
	private static final int COUNT = 10;

	// Each thread decrement by 1
	private static class TestRunnable implements Runnable {
		private final CountDownLatch countDownLatch;
		private byte[] lock;

		TestRunnable(CountDownLatch countDownLatch, byte[] byteArray) {
			this.countDownLatch = countDownLatch;
			this.lock = byteArray;
		}

		@Override
		public void run(a) {
			synchronized(this.lock) {
				System.out.println("Thread id: " + Thread.currentThread().getId());
				countDownLatch.countDown();
				System.out.println("Left number: " + countDownLatch.getCount());
			
				if( countDownLatch.getCount() == 0){
					System.out.println("!!!!!!!!!!!!!!!!!!! Game over!!!!!!!!!!!"); }}}}public void testThreadPool(a) throws InterruptedException {
		CountDownLatch countDownLatch = new CountDownLatch(COUNT);
		ExecutorService executorService = Executors.newFixedThreadPool(10);
		long bg = System.currentTimeMillis();
		final byte[] lock = new byte[0];  // Special instance variable
		for (int i = 0; i < COUNT; i++) {
			Runnable command = new TestRunnable(countDownLatch, lock);
			executorService.execute(command);
		}
		countDownLatch.await();
		System.out.println("testThreadPool:"
				+ (System.currentTimeMillis() - bg));
	}

	public void testNewThread(a) throws InterruptedException {
		CountDownLatch countDownLatch = new CountDownLatch(COUNT);
		long bg = System.currentTimeMillis();
		final byte[] lock = new byte[0];  // Special instance variable
		for (int i = 0; i < COUNT; i++) {
			Runnable command = new TestRunnable(countDownLatch, lock);
			Thread thread = new Thread(command);
			thread.start();
		}
		countDownLatch.await();
		System.out
				.println("testNewThread:" + (System.currentTimeMillis() - bg));
	}

	public static void main(String[] arg) {
		ThreadPoolTest a = new ThreadPoolTest();
		try {
			// a.testThreadPool();
			a.testNewThread();
		} catch(InterruptedException e) { e.printStackTrace(); }}}Copy the code

Output:

Thread id: 13

Left number: 9

Thread id: 22

Left number: 8

Thread id: 21

Left number: 7

Thread id: 20

Left number: 6

Thread id: 19

Left number: 5

Thread id: 17

Left number: 4

Thread id: 16

Left number: 3

Thread id: 18

Left number: 2

Thread id: 15

Left number: 1

Thread id: 14

Left number: 0

testNewThread:8

!!! Game over!!!

Example 3 – an example of a deadlock

package thread;

public class DeadLockExample {
	public static void main(String[] args) {
		final String resource1 = "ABAP";
		final String resource2 = "Java";
		// t1 tries to lock resource1 then resource2
		Thread t1 = new Thread() {
			public void run(a) {
				synchronized (resource1) {
					System.out.println("Thread 1: locked resource 1");
					try {
						Thread.sleep(100);
					} catch (Exception e) {
					}
					synchronized (resource2) {
						System.out.println("Thread 1: locked resource 2"); }}}}; Thread t2 =new Thread() {
			public void run(a) {
				synchronized (resource2) {
					System.out.println("Thread 2: locked resource 2");
					try {
						Thread.sleep(100);
					} catch (Exception e) {
					}
					synchronized (resource1) {
						System.out.println("Thread 2: locked resource 1"); }}}}; t1.start(); t2.start(); }}Copy the code