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