1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY )
。NORM_PRIORITY(5)
。代碼實現
```java
package com.ljw.thread;java
public class RunnableDemo {安全
public static void main(String[] args) { // 測試 RunnableDemo R = new RunnableDemo(); RunnableThread R1 = R.new RunnableThread("thread1"); R1.start(); RunnableThread R2 = R.new RunnableThread("thread2"); R2.start(); } class RunnableThread implements Runnable{ private String threadName; private Thread t; public RunnableThread(String name) { // TODO Auto-generated constructor stub threadName = name; System.out.println("建立線程 "+threadName); } @Override public void run() { System.out.println("正在運行線程:"+threadName); try { for(int i=10;i>0;i--) { System.out.println("線程:"+threadName+" 正在打印:"+i); Thread.sleep(50); } }catch(Exception e) { e.printStackTrace(); } System.out.println("線程:"+threadName+" 正在退出......"); } public void start() { System.out.println("開始線程 "+threadName); if(t == null) { t = new Thread(this, threadName); t.start(); } } }
}併發
```ide
代碼實現
```java
package com.ljw.thread;工具
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;oop
public class CallableThreadTest implements Callable
public static void main(String[] args)
{
CallableThreadTest ctt = new CallableThreadTest();
FutureTask
for(int i = 0;i < 10;i++)
{
System.out.println(Thread.currentThread().getName()+" 的循環變量i的值"+i);
if(i%2==0)
{
new Thread(ft,"有返回值的線程").start();
}
}
try
{
System.out.println("子線程的返回值:"+ft.get());
} catch (InterruptedException e)
{
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
}
} @Override public Integer call() throws Exception { int i = 0; for(;i<10;i++) { System.out.println(Thread.currentThread().getName()+" "+i); } return i; }
}
```測試
synchronized方法
或者synchronized代碼塊
時,其餘線程對該對象的該synchronized方法
或者synchronized代碼塊
的訪問將被阻塞。synchronized方法
或者synchronized代碼塊
時,其餘線程仍然能夠訪問該對象的非同步代碼塊。synchronized方法
或者synchronized代碼塊
時,其餘線程對該對象的其餘的synchronized方法
或者synchronized代碼塊
的訪問將被阻塞。package com.ljw.thread; public class RunnableTest { public static void main(String[] args) { class MyRunnable implements Runnable{ @Override public void run() { synchronized (this) { for(int i=0;i<5;i++) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 正在進行打印 " +i); } } } } Runnable runnable = new MyRunnable(); Thread t1 = new Thread(runnable,"t1"); Thread t2 = new Thread(runnable,"t2"); t1.start(); t2.start(); } }運行結果:
t1 正在進行打印 0 t1 正在進行打印 1 t1 正在進行打印 2 t1 正在進行打印 3 t1 正在進行打印 4 t2 正在進行打印 0 t2 正在進行打印 1 t2 正在進行打印 2 t2 正在進行打印 3 t2 正在進行打印 4
public class ThreadTest { public static void main(String[] args) { class MyThread extends Thread{ public MyThread(String name){ super(name); } @Override public void run() { synchronized(this){ for(int i=0;i<10;i++){ try { Thread.sleep(100); System.out.println(Thread.currentThread().getName()+" 正在進行打印 "+i); } catch (InterruptedException e) { e.printStackTrace(); } } } } } Thread t1 = new MyThread("t1"); Thread t2 = new MyThread("t2"); t1.start(); t2.start(); } }
運行結果:
t2 正在進行打印 0 t1 正在進行打印 0 t2 正在進行打印 1 t1 正在進行打印 1 t1 正在進行打印 2 t2 正在進行打印 2 t2 正在進行打印 3 t1 正在進行打印 3 t1 正在進行打印 4 t2 正在進行打印 4
對比結果:發現實例1的兩個線程是一個結束後,另外一個才運行,實例2的是交叉運行,在run()方法中都有synchronized(this),爲何結果不同?this
分析:synchronized(this)中的this是指當前對象,即synchronized(this)所在類對應的當前對象。它的做用是獲取獲取當前對象的同步鎖。對於實例2中的synchronized(this)中的this表明的是MyThread對象,t1和t2是兩個不一樣的MyThread對象,所以t1和t2在執行synchronized(this)時獲取的是不一樣對象的同步鎖。對於實例1來講,synchronized(this)中的this表明的時候MyRunnable對象,t1和t2是共同一個MyRunnable對象,所以,一個線程獲取了對象的同步鎖,會形成另外一個線程的等待。操作系統
synchronized方法
是用synchronized修飾方法,這是一種粗粒度鎖;這個同步方法(非static方法)無需顯式指定同步監視器,同步方法的同步監視器是this,也就是調用該方法的對象。synchronized代碼塊
是用synchronized修飾代碼塊,這是一種細粒度鎖。線程開始執行同步代碼塊以前,必須先得到對同步監視器的鎖定,任什麼時候候只能有一個線程能夠得到對同步監視器的鎖定,當同步代碼塊執行完成後,該線程會釋放對同步監視器的鎖定。雖然Java容許使用任何對象做爲同步監視器,但同步監視器的目的就是爲了阻止兩個線程對同一個共享資源進行併發訪問,所以一般推薦使用可能被併發訪問的共享資源充當同步監視器。public class SnchronizedTest { public static void main(String[] args) { class Demo { // synchronized方法 public synchronized void synMethod() { for(int i=0; i<1000000; i++) ; } public void synBlock() { // synchronized代碼塊 synchronized( this ) { for(int i=0; i<1000000; i++) ; } } } } }
pulbic class Something { public synchronized void isSyncA(){} public synchronized void isSyncB(){} public static synchronized void cSyncA(){} public static synchronized void cSyncB(){} }
假設,類Something有兩個實例(對象)分別爲x和y。分析下面4組表達式獲取鎖的狀況。
package com.ljw.thread; public class WaitDemo { public static void main(String[] args) { class ThreadTest extends Thread{ @Override public void run() { synchronized (this) { System.out.println("開始運行線程 "+Thread.currentThread().getName()); System.out.println("喚醒線程notify()"); notify(); } } } ThreadTest thread1 = new ThreadTest(); thread1.start(); synchronized (thread1) { try { System.out.println("主線程進入阻塞,釋放thread對象的同步鎖,wait()"); thread1.wait(); // wait()是讓當前線程進入阻塞狀態,wait()是在主線程中執行, } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("主線程繼續進行"); } }
package com.ljw.thread; public class YieldTest { public static void main(String[] args) { class ThreadA extends Thread{ public ThreadA(String name){ super(name); } @Override public synchronized void run() { for(int i=0;i<5;i++){ System.out.println(" "+this.getName()+" "+i); if(i%2 == 0){ Thread.yield(); } } } } ThreadA t1 = new ThreadA("t1"); ThreadA t2 = new ThreadA("t2"); t1.start(); t2.start(); } }
運行結果(不惟一):
t1 0 t2 0 t1 1 t1 2 t2 1 t1 3 t2 2 t1 4 t2 3 t2 4
結果說明:
線程t1在能被2整除的時候,並不必定切換到線程2。這代表,yield()方法雖然可讓線程由「運行狀態」進入到「就緒狀態」;可是,它不必定會讓其餘線程獲取CPU執行權(其餘線程進入到「運行狀態」)。即時這個「其餘線程」與當前調用yield()的線程具備相同的優先級。
@Override public void run() { try { // 1. isInterrupted()保證,只要中斷標記爲true就終止線程。 while (!isInterrupted()) { // 執行任務... } } catch (InterruptedException ie) { // 2. InterruptedException異常保證,當InterruptedException異常產生時,線程被終止。 } }
public class InterruptBlock { /** * @param args */ public static void main(String[] args) { class MyThread extends Thread{ public MyThread(String name){ super(name); } @Override public void run() { try { int i=0; while(!isInterrupted()){ Thread.sleep(100); i++; System.out.println(Thread.currentThread().getName()+ " ("+this.getState()+") loop "+i); } } catch (InterruptedException e) { e.printStackTrace(); System.out.println(Thread.currentThread().getName()+ " ("+this.getState()+") catch InterruptedExecption"); } } } try { //新建 Thread t1 = new MyThread("t1"); System.out.println(t1.getName()+" ("+t1.getState()+" ) is new."); System.out.println("luo1:"+t1.isInterrupted()); //啓動 t1.start(); System.out.println(t1.getName()+" ("+t1.getState()+" ) is started."); System.out.println("luo2:"+t1.isInterrupted()); //主線程休眠300ms,而後主線程給t1發「中斷」指令 Thread.sleep(300); t1.interrupt(); System.out.println("luo3:"+t1.isInterrupted()); System.out.println(t1.getName()+" ("+t1.getState()+" ) is interrupted."); //主線程休眠300ms,而後查看t1的狀態 Thread.sleep(300); System.out.println(t1.getName()+" ("+t1.getState()+" ) is interrupted now ."); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
運行結果:
t1 (NEW ) is new. luo1:false t1 (RUNNABLE ) is started. luo2:false t1 (RUNNABLE) loop 1 t1 (RUNNABLE) loop 2 luo3:true t1 (RUNNABLE) loop 3 t1 (RUNNABLE ) is interrupted. t1 (TERMINATED ) is interrupted now .
package com.ljw.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolDemo { public static void main(String[] args) { // 主線程 // 線程池 ---> Executors工具類(工廠類) /* * newFixedThreadPool(int threadCount) 建立固定數量的線程池 * newCachedThreadPool() 建立動態數量的線程池 */ ExecutorService es = Executors.newFixedThreadPool(3); Runnable task = new MyTask(); // 提交任務 es.submit(task); es.submit(task); es.shutdown(); // 關閉線程池,則表示不在接收新任務,不表明正在線程池的任務會停掉 } } class MyTask implements Runnable{ @Override public void run() { for(int i=0;i<100;i++) { System.out.println(Thread.currentThread().getName()+" MyTask "+i); } } }
package com.ljw.thread; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; /** * ReentrantLock類,重入鎖:Lock接口的實現類,與synchronized同樣具備互斥鎖功能 lock() 和 unlock() * ReentrantReadWriteLock類,讀寫鎖:一種支持一寫多讀的同步鎖,讀寫分離,分別分配讀鎖和寫鎖,在讀操做遠遠高於寫操做的環境中能夠提升效率 * 互斥規則: * 寫--寫:互斥,阻塞 * 讀--寫:互斥,阻塞 * 讀--讀:不互斥,不阻塞 * */ public class LockDemo { public static void main(String[] args) { ExecutorService es = Executors.newFixedThreadPool(20); Student s = new Student(); // ReentrantLock rLock = new ReentrantLock(); // 用ReenTrantLock加鎖運行時間20008ms ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); // 用讀寫鎖分別對讀寫任務加鎖運行時間3003ms ReadLock rl = rwLock.readLock(); WriteLock wl = rwLock.writeLock(); // 寫任務 Callable<Object> writeTask = new Callable<Object>() { @Override public Object call() throws Exception { // rLock.lock(); wl.lock(); try { Thread.sleep(1000); s.setValue(100); }finally { // rLock.unlock(); wl.unlock(); } return null; }}; // 讀任務 Callable<Object> readTask = new Callable<Object>() { @Override public Object call() throws Exception { // rLock.lock(); rl.lock(); try { Thread.sleep(1000); s.getValue(); }finally { // rLock.unlock(); rl.unlock(); } return null; }}; // 開始時間 long start = System.currentTimeMillis(); for(int i=0;i<2;i++) { // 寫任務執行 2 次 es.submit(writeTask); } for(int i=0;i<18;i++) { // 讀任務執行 18 次 es.submit(readTask); } es.shutdown(); // 中止線程池,不在接受新的任務,將現有任務所有執行完畢 while(true) { if(es.isTerminated()) { // 當線程池中全部任務執行完畢,返回true,不然返回false break; } } // 執行到這裏,說明線程池中全部任務都執行完畢,能夠計算結束時間 System.out.println(System.currentTimeMillis()-start); } } class Student { private int value; //讀 public int getValue() { return value; } //寫 public void setValue(int value) { this.value = value; } }
static <T> Collection<T> synchronizedCollection(Collection<T> c) //返回由指定集合支持的同步(線程安全)集合。 static <T> List<T> synchronizedList(List<T> list) //返回由指定列表支持的同步(線程安全)列表。 static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) //返回由指定地圖支持的同步(線程安全)映射。 static <K,V> NavigableMap<K,V> synchronizedNavigableMap(NavigableMap<K,V> m) //返回由指定的可導航地圖支持的同步(線程安全)可導航地圖。 static <T> NavigableSet<T> synchronizedNavigableSet(NavigableSet<T> s) //返回由指定的可導航集支持的同步(線程安全)可導航集。 static <T> Set<T> synchronizedSet(Set<T> s) //返回由指定集合支持的同步(線程安全)集。 static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m) //返回由指定的排序映射支持的同步(線程安全)排序映射。 static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s) //返回由指定的排序集支持的同步(線程安全)排序集。