Thread

public class Thread implements Runnable { private boolean single_step; private boolean     daemon = false; private boolean     stillborn = false; boolean started = false; private int priority; private volatile long nativePeer; private long eetop; private String name; private final Object lock = new Object(); private Thread threadQ; private Runnable target; private ThreadGroup group; private ClassLoader contextClassLoader; private AccessControlContext inheritedAccessControlContext; private static int threadInitNumber; private static synchronized int nextThreadNum() { return threadInitNumber++; } ThreadLocal.ThreadLocalMap threadLocals = null; ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; private long stackSize; private long nativeParkEventPointer; private long tid; private static long threadSeqNumber; private volatile int threadStatus = 0; private static synchronized long nextThreadID() { return ++threadSeqNumber; } volatile Object parkBlocker; private volatile Interruptible blocker; private final Object blockerLock = new Object(); public void blockedOn(Interruptible b) { synchronized (blockerLock) { blocker = b; } } public final static int MIN_PRIORITY = 1; public final static int NORM_PRIORITY = 5; public final static int MAX_PRIORITY = 10; public static native Thread currentThread(); public static native void yield(); public static void sleep(long millis) throws InterruptedException { Thread.sleep(millis, 0); } private static native void sleep(Object lock, long millis, int nanos) throws InterruptedException; public static void sleep(long millis, int nanos) throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("millis < 0: " + millis); } if (nanos < 0) { throw new IllegalArgumentException("nanos < 0: " + nanos); } if (nanos > 999999) { throw new IllegalArgumentException("nanos > 999999: " + nanos); } if (millis == 0 && nanos == 0) { if (Thread.interrupted()) { throw new InterruptedException(); } return; } long start = System.nanoTime(); long duration = (millis * NANOS_PER_MILLI) + nanos; Object lock = currentThread().lock; synchronized (lock) { while (true) { sleep(lock, millis, nanos); long now = System.nanoTime(); long elapsed = now - start; if (elapsed >= duration) { break; } duration -= elapsed; start = now; millis = duration / NANOS_PER_MILLI; nanos = (int) (duration % NANOS_PER_MILLI); } } } private void init(ThreadGroup g, Runnable target, String name, long stackSize) { Thread parent = currentThread(); if (g == null) { g = parent.getThreadGroup(); } g.addUnstarted(); this.group = g; this.target = target; this.priority = parent.getPriority(); this.daemon = parent.isDaemon(); setName(name); init2(parent); this.stackSize = stackSize; tid = nextThreadID(); } @Override protected Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); } public Thread(ThreadGroup group, Runnable target) { init(group, target, "Thread-" + nextThreadNum(), 0); } public Thread(String name) { init(null, null, name, 0); } public Thread(ThreadGroup group, String name) { init(group, null, name, 0); } Thread(ThreadGroup group, String name, int priority, boolean daemon) { this.group = group; this.group.addUnstarted(); if (name == null) { name = "Thread-" + nextThreadNum(); } this.name = name; this.priority = priority; this.daemon = daemon; init2(currentThread()); tid = nextThreadID(); } private void init2(Thread parent) { this.contextClassLoader = parent.getContextClassLoader(); this.inheritedAccessControlContext = AccessController.getContext(); if (parent.inheritableThreadLocals != null) { this.inheritableThreadLocals = ThreadLocal.createInheritedMap( parent.inheritableThreadLocals); } } public Thread(Runnable target, String name) { init(null, target, name, 0); } public Thread(ThreadGroup group, Runnable target, String name) { init(group, target, name, 0); } public Thread(ThreadGroup group, Runnable target, String name, long stackSize) { init(group, target, name, stackSize); } public synchronized void start() { if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this); started = false; try { nativeCreate(this, stackSize, daemon); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { } } } private native static void nativeCreate(Thread t, long stackSize, boolean daemon); @Override public void run() { if (target != null) { target.run(); } } private void exit() { if (group != null) { group.threadTerminated(this); group = null; } target = null; threadLocals = null; inheritableThreadLocals = null; inheritedAccessControlContext = null; blocker = null; uncaughtExceptionHandler = null; } @Deprecated public final void stop() { stop(new ThreadDeath()); } @Deprecated public final void stop(Throwable obj) { throw new UnsupportedOperationException(); } public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { nativeInterrupt(); b.interrupt(this); return; } } nativeInterrupt(); } public static native boolean interrupted(); public native boolean isInterrupted(); @Deprecated public void destroy() { throw new UnsupportedOperationException(); } public final boolean isAlive() { return nativePeer != 0; } @Deprecated public final void suspend() { throw new UnsupportedOperationException(); } @Deprecated public final void resume() { throw new UnsupportedOperationException(); } public final void setPriority(int newPriority) { ThreadGroup g; checkAccess(); if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); } if((g = getThreadGroup()) != null) { if (newPriority > g.getMaxPriority()) { newPriority = g.getMaxPriority(); } synchronized(this) { this.priority = newPriority; if (isAlive()) { nativeSetPriority(newPriority); } } } } public final int getPriority() { return priority; } public final void setName(String name) { checkAccess(); if (name == null) { throw new NullPointerException("name == null"); } synchronized (this) { this.name = name; if (isAlive()) { nativeSetName(name); } } } public final String getName() { return name; } public final ThreadGroup getThreadGroup() { if (getState() == Thread.State.TERMINATED) { return null; } return group; } public static int activeCount() { return currentThread().getThreadGroup().activeCount(); } public static int enumerate(Thread tarray[]) { return currentThread().getThreadGroup().enumerate(tarray); } @Deprecated public int countStackFrames() { return getStackTrace().length; } public final void join(long millis) throws InterruptedException { synchronized(lock) { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { lock.wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } lock.wait(delay); now = System.currentTimeMillis() - base; } } } } public final void join(long millis, int nanos) throws InterruptedException { synchronized(lock) { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos >= 500000 || (nanos != 0 && millis == 0)) { millis++; } join(millis); } } public final void join() throws InterruptedException { join(0); } public static void dumpStack() { new Exception("Stack trace").printStackTrace(); } public final void setDaemon(boolean on) { checkAccess(); if (isAlive()) { throw new IllegalThreadStateException(); } daemon = on; } public final boolean isDaemon() { return daemon; } public final void checkAccess() { } public String toString() { ThreadGroup group = getThreadGroup(); if (group != null) { return "Thread[" + getName() + "," + getPriority() + "," + group.getName() + "]"; } else { return "Thread[" + getName() + "," + getPriority() + "," +
                            "" + "]"; } } @CallerSensitive public ClassLoader getContextClassLoader() { return contextClassLoader; } public void setContextClassLoader(ClassLoader cl) { contextClassLoader = cl; } public static boolean holdsLock(Object obj) { return currentThread().nativeHoldsLock(obj); } private native boolean nativeHoldsLock(Object object); private static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0]; public StackTraceElement[] getStackTrace() { StackTraceElement ste[] = VMStack.getThreadStackTrace(this); return ste != null ? ste : EmptyArray.STACK_TRACE_ELEMENT; } public static Map<Thread, StackTraceElement[]> getAllStackTraces() { Map<Thread, StackTraceElement[]> map = new HashMap<Thread, StackTraceElement[]>(); int count = ThreadGroup.systemThreadGroup.activeCount(); Thread[] threads = new Thread[count + count / 2]; count = ThreadGroup.systemThreadGroup.enumerate(threads); for (int i = 0; i < count; i++) { map.put(threads[i], threads[i].getStackTrace()); } return map; } private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
                    new RuntimePermission("enableContextClassLoaderOverride"); private static class Caches { static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
            new ConcurrentHashMap<>(); static final ReferenceQueue<Class<?>> subclassAuditsQueue =
            new ReferenceQueue<>(); } private static boolean isCCLOverridden(Class cl) { if (cl == Thread.class) return false; processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); Boolean result = Caches.subclassAudits.get(key); if (result == null) { result = Boolean.valueOf(auditSubclass(cl)); Caches.subclassAudits.putIfAbsent(key, result); } return result.booleanValue(); } private static boolean auditSubclass(final Class subcl) { Boolean result = AccessController.doPrivileged( new PrivilegedAction<Boolean>() { public Boolean run() { for (Class cl = subcl; cl != Thread.class; cl = cl.getSuperclass()) { try { cl.getDeclaredMethod("getContextClassLoader", new Class[0]); return Boolean.TRUE; } catch (NoSuchMethodException ex) { } try { Class[] params = {ClassLoader.class}; cl.getDeclaredMethod("setContextClassLoader", params); return Boolean.TRUE; } catch (NoSuchMethodException ex) { } } return Boolean.FALSE; } } ); return result.booleanValue(); } public long getId() { return tid; } public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; } public State getState() { return State.values()[nativeGetStatus(started)]; } public interface UncaughtExceptionHandler { void uncaughtException(Thread t, Throwable e); } private volatile UncaughtExceptionHandler uncaughtExceptionHandler; private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler; public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { defaultUncaughtExceptionHandler = eh; } public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){ return defaultUncaughtExceptionHandler; } public UncaughtExceptionHandler getUncaughtExceptionHandler() { return uncaughtExceptionHandler != null ? uncaughtExceptionHandler : group; } public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) { checkAccess(); uncaughtExceptionHandler = eh; } private void dispatchUncaughtException(Throwable e) { getUncaughtExceptionHandler().uncaughtException(this, e); } static void processQueue(ReferenceQueue<Class<?>> queue, ConcurrentMap<? extends WeakReference<Class<?>>, ?> map) { Reference<? extends Class<?>> ref; while((ref = queue.poll()) != null) { map.remove(ref); } } static class WeakClassKey extends WeakReference<Class<?>> { private final int hash; WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) { super(cl, refQueue); hash = System.identityHashCode(cl); } @Override public int hashCode() { return hash; } @Override public boolean equals(Object obj) { if (obj == this) return true; if (obj instanceof WeakClassKey) { Object referent = get(); return (referent != null) && (referent == ((WeakClassKey) obj).get()); } else { return false; } } } long threadLocalRandomSeed; int threadLocalRandomProbe; int threadLocalRandomSecondarySeed; private native void nativeSetName(String newName); private native void nativeSetPriority(int newPriority); private native int nativeGetStatus(boolean hasBeenStarted); private native void nativeInterrupt(); private static class ParkState { private static final int UNPARKED = 1; private static final int PREEMPTIVELY_UNPARKED = 2; private static final int PARKED = 3; } private static final int NANOS_PER_MILLI = 1000000; private int parkState = ParkState.UNPARKED; public final void unpark$() { synchronized(lock) { switch (parkState) { case ParkState.PREEMPTIVELY_UNPARKED: { break; } case ParkState.UNPARKED: { parkState = ParkState.PREEMPTIVELY_UNPARKED; break; } default /*parked*/: { parkState = ParkState.UNPARKED; lock.notifyAll(); break; } } } } public final void parkFor$(long nanos) { synchronized(lock) { switch (parkState) { case ParkState.PREEMPTIVELY_UNPARKED: { parkState = ParkState.UNPARKED; break; } case ParkState.UNPARKED: { long millis = nanos / NANOS_PER_MILLI; nanos %= NANOS_PER_MILLI; parkState = ParkState.PARKED; try { lock.wait(millis, (int) nanos); } catch (InterruptedException ex) { interrupt(); } finally { if (parkState == ParkState.PARKED) { parkState = ParkState.UNPARKED; } } break; } default /*parked*/: { throw new AssertionError("Attempt to repark"); } } } } public final void parkUntil$(long time) { synchronized(lock) { long delayMillis = time - System.currentTimeMillis(); if (delayMillis <= 0) { parkState = ParkState.UNPARKED; } else { parkFor$(delayMillis * NANOS_PER_MILLI); } } } }
public class Object { private transient Class<?> shadow$_klass_; private transient int shadow$_monitor_; public final Class<?> getClass() { return shadow$_klass_; } public int hashCode() { int lockWord = shadow$_monitor_; final int lockWordStateMask = 0xC0000000;  // Top 2 bits.
        final int lockWordStateHash = 0x80000000;  // Top 2 bits are value 2 (kStateHash).
        final int lockWordHashMask = 0x0FFFFFFF;  // Low 28 bits.
        if ((lockWord & lockWordStateMask) == lockWordStateHash) { return lockWord & lockWordHashMask; } return System.identityHashCode(this); } public boolean equals(Object obj) { return (this == obj); } protected Object clone() throws CloneNotSupportedException { if (!(this instanceof Cloneable)) { throw new CloneNotSupportedException("Class " + getClass().getName() +
                                                 " doesn't implement Cloneable"); } return internalClone(); } private native Object internalClone(); public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } public final native void notify(); public final native void notifyAll(); public final native void wait() throws InterruptedException; public final void wait(long millis) throws InterruptedException { wait(millis, 0); } public final native void wait(long millis, int nanos) throws InterruptedException; protected void finalize() throws Throwable { } }

 --------------------------------------------------------------------java

Java從入門到精通 19多線程數組

1進程與線程
進程 一個執行中的程序
線程 程序中單個順序的控制流安全

2認識線程
實現Runnable接口相對於基礎Thread好處
適合多個相同程序代碼的線程去處理同一資源的狀況
能夠避免因爲Java的單繼承特性帶來的侷限
加強程序的健壯性 代碼可以被多個線程共享 代碼與數據是獨立的多線程

3線程的狀態
public enum State {
NEW, //至今還沒有啓動的線程
RUNNABLE, //正在Java虛擬機中執行的線程
BLOCKED, //受阻塞並等待某個監視器鎖的線程
WAITING, //無限期等待另外一個線程來執行特定操做的線程
TIMED_WAITING, //等待另外一個線程執行特定操做(取決於指定等待時間)的線程
TERMINATED; //已退出的線程
}dom

4線程操做的一些方法jvm

activeCount 返回線程組中目前活動線程數目
currentThread 返回目前正在執行線程
destroy 銷燬線程
enumerate 將當前和子線程組中的活動線程複製至指定的線程數組
getName 返回線程名稱
getPriority 返回線程優先級
getThreadGroup 返回線程線程組
interrupted 中斷
isAlive 判斷線程是否活動
isInterrupted
join 等待線程死亡
join 等待millis毫秒後 線程死亡
join 等待millis毫秒加上nanos微妙後 線程死亡
run 執行線程
setName 設定線程名稱
setPriority 設定線程優先級
sleep 使目前正在執行的線程休眠millis毫秒
sleep 使目前正在執行的線程休眠millis毫秒加上nanos微妙
start 開始執行線程
toString
yield 將目前正在執行的線程暫停 容許其它線程執行ide

setDaemon 後臺線程函數

5多線程的同步
synchronized優化

6線程間的通訊
wait 告訴當前線程放棄監視器並進入睡眠狀態 直到其它線程進入同一監視器並調用notify爲止
notify 喚醒同一對象監視器中調用wait的第1個線程
notifyAll 喚醒同一對象監視器中調用wait的全部線程 最高優先級線程首先被喚醒並執行this

7線程生命週期的控制

-----------------------------------------------------------------------------------------------------------------------------------

/*
進程:正在進行中的程序(直譯).
        
線程:就是進程中一個負責程序執行的控制單元(執行路徑)
一個進程中能夠多執行路徑,稱之爲多線程。

一個進程中至少要有一個線程。

開啓多個線程是爲了同時運行多部分代碼。

每個線程都有本身運行的內容。這個內容能夠稱爲線程要執行的任務。

多線程好處:解決了多部分同時運行的問題。

多線程的弊端:線程太多回到效率的下降。


其實應用程序的執行都是cpu在作着快速的切換完成的。這個切換是隨機的。


JVM啓動時就啓動了多個線程,至少有兩個線程能夠分析的出來。

1,執行main函數的線程,
        該線程的任務代碼都定義在main函數中。

2,負責垃圾回收的線程。


*/


class Demo extends Object
{
    public void finalize()
    {
        System.out.println("demo ok");
    }
}


class  ThreadDemo
{
    public static void main(String[] args) 
    {

        new Demo();
        new Demo();
        new Demo();
        System.gc();
        System.out.println("Hello World!");
    }
}


/*
如何建立一個線程呢?

建立線程方式一:繼承Thread類。

步驟:
1,定義一個類繼承Thread類。
2,覆蓋Thread類中的run方法。
3,直接建立Thread的子類對象建立線程。
4,調用start方法開啓線程並調用線程的任務run方法執行。



能夠經過Thread的getName獲取線程的名稱 Thread-編號(從0開始)

主線程的名字就是main。
*/

class Demo extends Thread
{
    private String name;
    Demo(String name)
    {
        super(name);
        //this.name = name;
    }
    public void run()
    {
        for(int x=0; x<10; x++)
        {
            //for(int y=-9999999; y<999999999; y++){}
            System.out.println(name+"....x="+x+".....name="+Thread.currentThread().getName());
        }
    }
}




class ThreadDemo2 
{
    public static void main(String[] args) 
    {

        /*
        建立線程的目的是爲了開啓一條執行路徑,去運行指定的代碼和其餘代碼實現同時運行。
        
        而運行的指定代碼就是這個執行路徑的任務。

        jvm建立的主線程的任務都定義在了主函數中。

        而自定義的線程它的任務在哪兒呢?
        Thread類用於描述線程,線程是須要任務的。因此Thread類也對任務的描述。
        這個任務就經過Thread類中的run方法來體現。也就是說,run方法就是封裝自定義線程運行任務的函數。
        
        run方法中定義就是線程要運行的任務代碼。

        開啓線程是爲了運行指定代碼,因此只有繼承Thread類,並複寫run方法。
        將運行的代碼定義在run方法中便可。 


        */
//
//        Thread t1 = new Thread();

        Demo d1 = new Demo("旺財");
        Demo d2 = new Demo("xiaoqiang");
        d1.start();//開啓線程,調用run方法。
        
        d2.start();
        System.out.println("over...."+Thread.currentThread().getName());
    }
}
//調用run和調用start有什麼區別?



/*
建立線程的第一種方式:繼承Thread類。

建立線程的第二種方式:實現Runnable接口。

1,定義類實現Runnable接口。
2,覆蓋接口中的run方法,將線程的任務代碼封裝到run方法中。
3,經過Thread類建立線程對象,並將Runnable接口的子類對象做爲Thread類的構造函數的參數進行傳遞。
    爲何?由於線程的任務都封裝在Runnable接口子類對象的run方法中。
    因此要在線程對象建立時就必須明確要運行的任務。

4,調用線程對象的start方法開啓線程。


實現Runnable接口的好處:
1,將線程的任務從線程的子類中分離出來,進行了單獨的封裝。
    按照面向對象的思想將任務的封裝成對象。
2,避免了java單繼承的侷限性。

因此,建立線程的第二種方式較爲經常使用。




*/


class Demo implements Runnable//extends Fu //準備擴展Demo類的功能,讓其中的內容能夠做爲線程的任務執行。
                    //經過接口的形式完成。
{
    public void run()
    {
        show();
    }
    public void show()
    {
        for(int x=0; x<20; x++)
        {
            System.out.println(Thread.currentThread().getName()+"....."+x);
        }
    }
}


class  ThreadDemo
{
    public static void main(String[] args) 
    {    
        Demo d = new Demo();
        Thread t1 = new Thread(d);
        Thread t2 = new Thread(d);
        t1.start();
        t2.start();
    }
}


/*
需求:賣票。
*/



/*
線程安全問題產生的緣由:

1,多個線程在操做共享的數據。
2,操做共享數據的線程代碼有多條。

當一個線程在執行操做共享數據的多條代碼過程當中,其餘線程參與了運算。
就會致使線程安全問題的產生。 


解決思路;
就是將多條操做共享數據的線程代碼封裝起來,當有線程在執行這些代碼的時候,
其餘線程時不能夠參與運算的。
必需要當前線程把這些代碼都執行完畢後,其餘線程才能夠參與運算。 

在java中,用同步代碼塊就能夠解決這個問題。

同步代碼塊的格式:
synchronized(對象)
{
    須要被同步的代碼 ;
}

同步的好處:解決了線程的安全問題。


同步的弊端:相對下降了效率,由於同步外的線程的都會判斷同步鎖。


同步的前提:同步中必須有多個線程並使用同一個鎖。

*/

class Ticket implements Runnable//extends Thread
{
    private  int num = 100;

    Object obj = new Object();
    public void run()
    {
        while(true)
        {
            synchronized(obj)
            {
                if(num>0)
                {
                    try{Thread.sleep(10);}catch (InterruptedException e){}
                    
                    System.out.println(Thread.currentThread().getName()+".....sale...."+num--);
                }
            }
        }
    }
}


class  TicketDemo
{
    public static void main(String[] args) 
    {

        Ticket t = new Ticket();//建立一個線程任務對象。

        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        Thread t3 = new Thread(t);
        Thread t4 = new Thread(t);

        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}

/*
需求:儲戶,兩個,每一個都到銀行存錢每次存100,,共存三次。
*/

class Bank
{
    private int sum;
    public synchronized void add(int num) 
    {
            sum = sum + num;
            try{Thread.sleep(10);}catch(InterruptedException e){}
            System.out.println("sum="+sum);
    }
}


class Cus implements Runnable
{
    private Bank b = new Bank();
    public void run()
    {
        for(int x=0; x<3; x++)
        {
            b.add(100);
        }
    }
}


class BankDemo 
{
    public static void main(String[] args) 
    {
        Cus c = new Cus();
        Thread t1 = new Thread(c);
        Thread t2 = new Thread(c);
        t1.start();
        t2.start();
    }
}


/*
同步函數的使用的鎖是this;

同步函數和同步代碼塊的區別:
同步函數的鎖是固定的this。

同步代碼塊的鎖是任意的對象。

建議使用同步代碼塊。
*/

/*
靜態的同步函數使用的鎖是  該函數所屬字節碼文件對象 
能夠用 getClass方法獲取,也能夠用當前  類名.class 表示。
*/


/*
多線程下的單例

*/

//餓漢式
class Single
{
    private static final Single s = new Single();
    private Single(){}
    public static Single getInstance()
    {
        return s;
    }
}



//懶漢式

加入同步爲了解決多線程安全問題。

加入雙重判斷是爲了解決效率問題。




class Single
{
    private static Single s = null;

    private Single(){}

    public static Single getInstance()
    {
        if(s==null)
        {
            synchronized(Single.class)        
            {
                if(s==null)
        //                -->0 -->1
                    s = new Single();
            }
        }
        return s;
    }
}
class  SingleDemo
{
    public static void main(String[] args) 
    {
        System.out.println("Hello World!");
    }
}


class Test implements Runnable
{
    private boolean flag;
    Test(boolean flag)
    {
        this.flag = flag;
    }

    public void run()
    {
        
        if(flag)
        {
            while(true)
                synchronized(MyLock.locka)
                {
                    System.out.println(Thread.currentThread().getName()+"..if   locka....");
                    synchronized(MyLock.lockb)                {
                        
                        System.out.println(Thread.currentThread().getName()+"..if   lockb....");
                    }
                }
        }
        else
        {
            while(true)            
                synchronized(MyLock.lockb)
                {
                    System.out.println(Thread.currentThread().getName()+"..else  lockb....");
                    synchronized(MyLock.locka)
                    {
                        System.out.println(Thread.currentThread().getName()+"..else   locka....");
                    }
                }
        }

    }

}

class MyLock
{
    public static final Object locka = new Object();
    public static final Object lockb = new Object();
}




class DeadLockTest 
{
    public static void main(String[] args) 
    {
        Test a = new Test(true);
        Test b = new Test(false);

        Thread t1 = new Thread(a);
        Thread t2 = new Thread(b);
        t1.start();
        t2.start();
    }
}




/*
等待/喚醒機制。 

涉及的方法:

1,wait(): 讓線程處於凍結狀態,被wait的線程會被存儲到線程池中。
2,notify():喚醒線程池中一個線程(任意).
3,notifyAll():喚醒線程池中的全部線程。

這些方法都必須定義在同步中。
由於這些方法是用於操做線程狀態的方法。
必需要明確到底操做的是哪一個鎖上的線程。


爲何操做線程的方法wait notify notifyAll定義在了Object類中? 

由於這些方法是監視器的方法。監視器其實就是鎖。
鎖能夠是任意的對象,任意的對象調用的方式必定定義在Object類中。

*/
//資源
class Resource
{
    String name;
    String sex;
    boolean flag = false;
}


//輸入
class Input implements Runnable
{
    Resource r ;
//    Object obj = new Object();
    Input(Resource r)
    {
        this.r = r;
    }
    public void run()
    {
        int x = 0;
        while(true)
        {
            synchronized(r)
            {
                if(r.flag)
                    try{r.wait();}catch(InterruptedException e){}
                if(x==0)
                {
                    r.name = "mike";
                    r.sex = "nan";
                }
                else
                {
                    r.name = "麗麗";
                    r.sex = "女女女女女女";
                }
                r.flag = true;
                r.notify();
            }
            x = (x+1)%2;

        }
    }
}
//輸出
class Output implements Runnable
{

    Resource r;
//    Object obj = new Object();
    Output(Resource r)
    {
        this.r = r;
    }

    public void run()
    {
        while(true)
        {
            synchronized(r)
            {
                if(!r.flag)
                    try{r.wait();}catch(InterruptedException e){}
                System.out.println(r.name+"....."+r.sex);
                r.flag = false;
                r.notify();
            }
        }
    }
}



class  ResourceDemo2
{
    public static void main(String[] args) 
    {
        //建立資源。
        Resource r = new Resource();
        //建立任務。
        Input in = new Input(r);
        Output out = new Output(r);
        //建立線程,執行路徑。
        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);
        //開啓線程
        t1.start();
        t2.start();
    }
}


class Resource
{
    private String name;
    private String sex;
    private boolean flag = false;

    public synchronized void set(String name,String sex)
    {
        if(flag)
            try{this.wait();}catch(InterruptedException e){}
        this.name = name;
        this.sex = sex;
        flag = true;
        this.notify();
    }

    public synchronized void out()
    {
        if(!flag)
            try{this.wait();}catch(InterruptedException e){}
        System.out.println(name+"...+...."+sex);
        flag = false;
        notify();
    }
}


//輸入
class Input implements Runnable
{
    Resource r ;
//    Object obj = new Object();
    Input(Resource r)
    {
        this.r = r;
    }
    public void run()
    {
        int x = 0;
        while(true)
        {
            if(x==0)
            {
                r.set("mike","nan");
            }
            else
            {
                r.set("麗麗","女女女女女女");
            }
            x = (x+1)%2;
        }
    }
}
//輸出
class Output implements Runnable
{

    Resource r;
//    Object obj = new Object();
    Output(Resource r)
    {
        this.r = r;
    }

    public void run()
    {
        while(true)
        {
            r.out();
        }
    }
}



class  ResourceDemo3
{
    public static void main(String[] args) 
    {
        //建立資源。
        Resource r = new Resource();
        //建立任務。
        Input in = new Input(r);
        Output out = new Output(r);
        //建立線程,執行路徑。
        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);
        //開啓線程
        t1.start();
        t2.start();
    }
}


/*
生產者,消費者。

多生產者,多消費者的問題。
if判斷標記,只有一次,會致使不應運行的線程運行了。出現了數據錯誤的狀況。
while判斷標記,解決了線程獲取執行權後,是否要運行!

notify:只能喚醒一個線程,若是本方喚醒了本方,沒有意義。並且while判斷標記+notify會致使死鎖。
notifyAll解決了本方線程必定會喚醒對方線程的問題。


*/

class Resource
{
    private String name;
    private int count = 1;
    private boolean flag = false;
    public synchronized void set(String name)//  
    {
        while(flag)
            try{this.wait();}catch(InterruptedException e){}//   t1    t0
        
        this.name = name + count;//烤鴨1  烤鴨2  烤鴨3
        count++;//2 3 4
        System.out.println(Thread.currentThread().getName()+"...生產者..."+this.name);//生產烤鴨1 生產烤鴨2 生產烤鴨3
        flag = true;
        notifyAll();
    }

    public synchronized void out()//  t3
    {
        while(!flag)
            try{this.wait();}catch(InterruptedException e){}    //t2  t3
        System.out.println(Thread.currentThread().getName()+"...消費者........"+this.name);//消費烤鴨1
        flag = false;
        notifyAll();
    }
}

class Producer implements Runnable
{
    private Resource r;
    Producer(Resource r)
    {
        this.r = r;
    }
    public void run()
    {
        while(true)
        {
            r.set("烤鴨");
        }
    }
}

class Consumer implements Runnable
{
    private Resource r;
    Consumer(Resource r)
    {
        this.r = r;
    }
    public void run()
    {
        while(true)
        {
            r.out();
        }
    }
}



class  ProducerConsumerDemo
{
    public static void main(String[] args) 
    {
        Resource r = new Resource();
        Producer pro = new Producer(r);
        Consumer con = new Consumer(r);

        Thread t0 = new Thread(pro);
        Thread t1 = new Thread(pro);
        Thread t2 = new Thread(con);
        Thread t3 = new Thread(con);
        t0.start();
        t1.start();
        t2.start();
        t3.start();

    }
}


/*
jdk1.5之後將同步和鎖封裝成了對象。 
並將操做鎖的隱式方式定義到了該對象中,
將隱式動做變成了顯示動做。

Lock接口: 出現替代了同步代碼塊或者同步函數。將同步的隱式鎖操做變成現實鎖操做。
同時更爲靈活。能夠一個鎖上加上多組監視器。
lock():獲取鎖。
unlock():釋放鎖,一般須要定義finally代碼塊中。


Condition接口:出現替代了Object中的wait notify notifyAll方法。
            將這些監視器方法單獨進行了封裝,變成Condition監視器對象。
            能夠任意鎖進行組合。
await();
signal();
signalAll();



*/

import java.util.concurrent.locks.*;

class Resource
{
    private String name;
    private int count = 1;
    private boolean flag = false;

//    建立一個鎖對象。
    Lock lock = new ReentrantLock();

    //經過已有的鎖獲取該鎖上的監視器對象。
//    Condition con = lock.newCondition();

    //經過已有的鎖獲取兩組監視器,一組監視生產者,一組監視消費者。
    Condition producer_con = lock.newCondition();
    Condition consumer_con = lock.newCondition();

    
    public  void set(String name)//  t0 t1
    {
        lock.lock();
        try
        {
            while(flag)
//            try{lock.wait();}catch(InterruptedException e){}//   t1    t0
            try{producer_con.await();}catch(InterruptedException e){}//   t1    t0
        
            this.name = name + count;//烤鴨1  烤鴨2  烤鴨3
            count++;//2 3 4
            System.out.println(Thread.currentThread().getName()+"...生產者5.0..."+this.name);//生產烤鴨1 生產烤鴨2 生產烤鴨3
            flag = true;
//            notifyAll();
//            con.signalAll();
            consumer_con.signal();
        }
        finally
        {
            lock.unlock();
        }
        
    }

    public  void out()// t2 t3
    {
        lock.lock();
        try
        {
            while(!flag)
//            try{this.wait();}catch(InterruptedException e){}    //t2  t3
            try{cousumer_con.await();}catch(InterruptedException e){}    //t2  t3
            System.out.println(Thread.currentThread().getName()+"...消費者.5.0......."+this.name);//消費烤鴨1
            flag = false;
//            notifyAll();
//            con.signalAll();
            producer_con.signal();
        }
        finally
        {
            lock.unlock();
        }
        
    }
}

class Producer implements Runnable
{
    private Resource r;
    Producer(Resource r)
    {
        this.r = r;
    }
    public void run()
    {
        while(true)
        {
            r.set("烤鴨");
        }
    }
}

class Consumer implements Runnable
{
    private Resource r;
    Consumer(Resource r)
    {
        this.r = r;
    }
    public void run()
    {
        while(true)
        {
            r.out();
        }
    }
}



class  ProducerConsumerDemo2
{
    public static void main(String[] args) 
    {
        Resource r = new Resource();
        Producer pro = new Producer(r);
        Consumer con = new Consumer(r);

        Thread t0 = new Thread(pro);
        Thread t1 = new Thread(pro);
        Thread t2 = new Thread(con);
        Thread t3 = new Thread(con);
        t0.start();
        t1.start();
        t2.start();
        t3.start();

    }
}

/*
wait 和 sleep 區別?

1,wait能夠指定時間也能夠不指定。
   sleep必須指定時間。

2,在同步中時,對cpu的執行權和鎖的處理不一樣。
    wait:釋放執行權,釋放鎖。
    sleep:釋放執行權,不釋放鎖。

 
中止線程:
1,stop方法。

2,run方法結束。

怎麼控制線程的任務結束呢?
任務中都會有循環結構,只要控制住循環就能夠結束任務。

控制循環一般就用定義標記來完成。

可是若是線程處於了凍結狀態,沒法讀取標記。如何結束呢?

可使用interrupt()方法將線程從凍結狀態強制恢復到運行狀態中來,讓線程具有cpu的執行資格。 

當時強制動做會發生了InterruptedException,記得要處理

/*
多線程總結:

1,進程和線程的概念。
    |--進程:
    |--線程:

2,jvm中的多線程體現。
    |--主線程,垃圾回收線程,自定義線程。以及他們運行的代碼的位置。

3,何時使用多線程,多線程的好處是什麼?建立線程的目的?
    |--當須要多部分代碼同時執行的時候,可使用。

4,建立線程的兩種方式。★★★★★
    |--繼承Thread
        |--步驟
    |--實現Runnable
        |--步驟
    |--兩種方式的區別?

5,線程的5種狀態。
    對於執行資格和執行權在狀態中的具體特色。
    |--被建立:
    |--運行:
    |--凍結:
    |--臨時阻塞:
    |--消亡:

6,線程的安全問題。★★★★★
    |--安全問題的緣由:
    |--解決的思想:
    |--解決的體現:synchronized
    |--同步的前提:可是加上同步還出現安全問題,就須要用前提來思考。
    |--同步的兩種表現方法和區別:
    |--同步的好處和弊端:
    |--單例的懶漢式。
    |--死鎖。
    

7,線程間的通訊。等待/喚醒機制。
    |--概念:多個線程,不一樣任務,處理同一資源。 
    |--等待喚醒機制。使用了鎖上的 wait notify notifyAll.  ★★★★★
    |--生產者/消費者的問題。並多生產和多消費的問題。  while判斷標記。用notifyAll喚醒對方。 ★★★★★
    |--JDK1.5之後出現了更好的方案,★★★
        Lock接口替代了synchronized  
        Condition接口替代了Object中的監視方法,並將監視器方法封裝成了Condition
        和之前不一樣的是,之前一個鎖上只能有一組監視器方法。如今,一個Lock鎖上能夠多組監視器方法對象。
        能夠實現一組負責生產者,一組負責消費者。 
    |--wait和sleep的區別。★★★★★

    

8,中止線程的方式。
    |--原理:
    |--表現:--中斷。

9,線程常見的一些方法。
    |--setDaemon()
    |--join();
    |--優先級
    |--yield();
    |--在開發時,可使用匿名內部類來完成局部的路徑開闢。 








class  
{
    public static void main(String[] args) 
    {
        System.out.println("Hello World!");
    }
}



Java內存模型

全部變量都存儲在主內存中 每條線程有本身的工做內存
線程對變量的全部操做必須在工做內存中進行
線程間變量的傳遞須要經過主內存來完成

主內存與工做內存的交互協議由8種操做來完成
鎖定 解鎖 讀取 載入 使用 賦值 存儲 寫入

volatile 語義
volatile修飾的變量保存對全部線程的可見性
禁止指令重排序優化

原子性 對基本數據類型的訪問讀寫是具有原子性的
可見性 當一個線程修改了共享變量的值 其餘線程可以當即得知這個修改
有序性 本線程內觀察全部操做都是有序 在一個線程中觀察另外一個線程 全部操做都無序

先行發生原則
程序次序 管程鎖定 volatile變量 線程啓動 線程終止 線程中斷 對象終結 傳遞性


*/
相關文章
相關標籤/搜索