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从入门到精通 19多线程

1进程与线程
进程 一个执行中的程序
线程 程序中单个顺序的控制流

2认识线程
实现Runnable接口相对于基础Thread好处
适合多个相同程序代码的线程去处理同一资源的情况
可以避免由于Java的单继承特性带来的局限
增强程序的健壮性 代码能够被多个线程共享 代码与数据是独立的

3线程的状态
public enum State {
NEW, //至今尚未启动的线程
RUNNABLE, //正在Java虚拟机中执行的线程
BLOCKED, //受阻塞并等待某个监视器锁的线程
WAITING, //无限期等待另一个线程来执行特定操作的线程
TIMED_WAITING, //等待另一个线程执行特定操作(取决于指定等待时间)的线程
TERMINATED; //已退出的线程
}

4线程操作的一些方法

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 将目前正在执行的线程暂停 允许其它线程执行

setDaemon 后台线程

5多线程的同步
synchronized

6线程间的通信
wait 告诉当前线程放弃监视器并进入睡眠状态 直到其它线程进入同一监视器并调用notify为止
notify 唤醒同一对象监视器中调用wait的第1个线程
notifyAll 唤醒同一对象监视器中调用wait的所有线程 最高优先级线程首先被唤醒并执行

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变量 线程启动 线程终止 线程中断 对象终结 传递性


*/

 

posted @ 2017-08-23 15:44  幻奕  阅读(367)  评论(0编辑  收藏  举报