Thread、Runnable、synchronized关键字

The difference between Thread and RunRunnable implementing threads

/**
 * <p>Thread与RunRunnable</P>
 *
 * @author
 *
 */

/*
 * Implement the Runnable interface
 */
class ImpRunnable implements Runnable{
	
	private int count = 1;

	@Override
	public void run() {
		
		System.out.println(Thread.currentThread().getName()+" : "+(count++));
		
	}
	
}
/**
* Inherit Thread
*/
class ExtThread extends Thread{
	
	private int count = 1;
	
	@Override
	public void run() {
		
		System.out.println(Thread.currentThread().getName()+" : "+(count++));

	}
}

public class ThreadDemo {
	
	public static void main(String[] args) throws Exception {
		
		/*
		 * Multiple threads share an object
		 * The run method of the shared imp object
		 */
		ImpRunnable imp = new ImpRunnable();								
		Thread t1 = new Thread(imp);
		t1.start();
		Thread.sleep(1000);
		Thread t2 = new Thread(imp);
		t2.start();
		Thread.sleep(1000);
		Thread t3 = new Thread(imp);
		t3.start();
		Thread.sleep(1000);
		System.out.println("---------------------------------");
		
		/**
		 * Each thread is an instance, using its own run method
		 */
		ExtThread t4 = new ExtThread();
		t4.start();
		Thread.sleep(1000);
		ExtThread t5 = new ExtThread();
		t5.start();
		Thread.sleep(1000);
		ExtThread t6 = new ExtThread();
		t6.start();
		Thread.sleep(1000);
		System.out.println("---------------------------------");
		
		/**
		 * One thread uses one object, so the result is consistent with ExtThread
		 */
		Thread t7 = new Thread(new ImpRunnable());
		t7.start();
		Thread.sleep(1000);
		Thread t8 = new Thread(new ImpRunnable());
		t8.start();
		Thread.sleep(1000);
	}
	

}

/**
 * result:
 *  
 *	Thread-0 : 1
	Thread-1 : 2
	Thread-2 : 3
	---------------------------------
	Thread-3 : 1
	Thread-4 : 1
	Thread-5 : 1
	---------------------------------
	Thread-6 : 1
	Thread-7 : 1
 *
 * Implement the Runnable interface, you can create only one instance of the class, and can be shared by multiple threads.
 * While inheriting the Thread class, a different instance must be created for each thread. So each instance of the class is allocated a different memory space, each starting with Count=1.
 *
 *
 */


Synchronized keyword

/**
 * <p>synchronized keyword locks itself</p>
 *
 */


class SyncThread implements Runnable{
	
	private static int count = 0;
	
	@Override
	public  void run() {
		
		// lock the object
		/*synchronized (this) {
			 for (int i = 0; i < 5; i++) {
		            try {
		               System.out.println(Thread.currentThread().getName() + ":" + (count++));
		               Thread.sleep(100);
		            } catch (InterruptedException e) {
		               e.printStackTrace ();
		            }
		     }
		 }*/
		
		   method();
	   }	
        
		//The effect of the modification method is the same as above
	    public synchronized void method() {
	    	
	    	 for (int i = 0; i < 5; i++) {
		            try {
		               System.out.println(Thread.currentThread().getName() + ":" + (count++));
		               Thread.sleep(100);
		            } catch (InterruptedException e) {
		               e.printStackTrace ();
		            }
		     }
	    }
	
}
public class SyncThreadDemo1{
	
	  public static void main(String[] args) {
		  
		    SyncThread syt1 = new SyncThread();
			//SyncThread syt2 = new SyncThread();
			
			Thread t1 = new Thread(syt1,"t1");
			Thread t2 = new Thread(syt1,"t2");
			
			t1.start();
			t2.start();
		
	  }
	
	
}

/**
 * 未加synchronized
	t2:0
	t1:1
	t1:2
	t2:3
	t2:4
	t1:5
	t1:6
	t2:7
	t1:8
	t2:9
	
      加synchronized(this)
	t2:0
	t2:1
	t2:2
	t2:3
	t2:4
	t1:5
	t1:6
	t1:7
	t1:8
	t1:9
	
	When two concurrent threads (t1 and t2) access a synchronized block of code in the same object (syncThread),
	Only one thread can be executed at the same time, the other thread is blocked,
	The block of code cannot be executed until the current thread has finished executing the block of code. t1 and t2 are mutually exclusive,
	Because the current object is locked when the synchronized code block is executed, the object lock can only be released after the code block is executed.
	The next thread can execute and lock the object.
	
	
	Writing method 1 modifies a method, writing method 2 modifies a code block, but writing method 1 and writing method 2 are equivalent, both of which lock the content of the entire method.

    The synchronized keyword cannot be inherited.
        Although synchronized can be used to define methods, synchronized is not part of the method definition,
        Therefore, the synchronized keyword cannot be inherited. If a method in the parent class uses the synchronized keyword,
        And this method is overridden in the subclass, this method in the subclass is not synchronized by default,
        Instead, you must explicitly add the synchronized keyword to this method of the subclass.
        Of course, you can also call the corresponding method in the parent class in the subclass method, so that although the method in the subclass is not synchronized,
        But the subclass calls the synchronization method of the superclass (super.method();), so the method of the subclass is equivalent to synchronization.
 *
 */


/**
 * <p>synchronized keyword locks the object</p>
 *
 *
 */

class Counter {
	private Integer count;
	public Counter(Integer count) {
		this.count = count;
	}
	
	public void add() {
		count+=50;
	}
	
	public void sub() {
		count-=50;
	}
	
	public Integer getCount() {
		return count;
	}
	
}

class CountOperator implements Runnable{
	
	private Counter counter;
	
	public CountOperator(Counter counter) {
		this.counter = counter;
	}

	@Override
	public void run() {
		
		synchronized (counter) {
			counter.add();
			try {
				//deliberately wait 1 second
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace ();
			}
			counter.sub();
			System.out.println(Thread.currentThread().getName() + ":" + counter.getCount());
		}
	}
	
}

public class SyncThreadDemo2 {
	
	public static void main(String[] args) {
		Counter count = new Counter(100);
		
		CountOperator co = new CountOperator (count);
		
		/**
		 * 5 threads share co
		 */
		Thread t1 = new Thread(co);
		Thread t2 = new Thread(co);
		Thread t3 = new Thread(co);
		Thread t4 = new Thread(co);
		Thread t5 = new Thread(co);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		t5.start();
		
	}

}

/**

result:

Thread-1:100
Thread-3:100
Thread-4:100
Thread-0:100
Thread-2:100

------------------------------------------------------------
In the run method in the CountOperator class shared by five threads, we use synchronized to lock the counter object.
At this time, when a thread accesses the counter object, other threads trying to access the counter object will block,
Until the thread accesses the counter object ends.
That is to say, whoever gets the lock can run the code it controls.
*/


/**
 * <p>Synchronized modifies a static method</p>
 *
 *
 */

class SyncThread1 implements Runnable{
	
	private static int count = 0;
	
	public static synchronized void method() {
    	
	   	 for (int i = 0; i < 5; i++) {
		            try {
		               System.out.println(Thread.currentThread().getName() + ":" + (count++));
		               Thread.sleep(100);
		            } catch (InterruptedException e) {
		               e.printStackTrace ();
		            }
		     }
   }

	@Override
	public void run() {
		
		method();
	}
	
}

public class SyncThreadDemo3 {
      
	public static void main(String[] args) {
		
		SyncThread1 syt1 = new SyncThread1();
		SyncThread1 syt2 = new SyncThread1();
		
		Thread t1 = new Thread(syt1,"t1");
		Thread t2 = new Thread(syt2,"t2");
		
		t1.start();
		t2.start();
	}
}

/**
 *
 *
 * syncThread1 and syncThread2 are two objects of SyncThread, but keep thread synchronization when t1 and t2 execute concurrently.
 * This is because the static method method is called in run,
 * while the static method belongs to the class,
 * So syncThread1 and syncThread2 are equivalent to using the same lock
 *
 *
 *
 *
 *
 * Regardless of whether the synchronized keyword is added to a method or an object, if the object it acts on is non-static, the lock it acquires is the object; if the object synchronized acts on a static method or a class, the lock it acquires is for Class, all objects of this class have the same lock.
      Each object has only one lock (lock) associated with it, whoever gets the lock can run the code it controls.
 *
 *
 *
 *
 *
 *
 * */

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324649516&siteId=291194637