当前位置: 首页 > news >正文

怎么做一个个人网站建网站的八个步骤

怎么做一个个人网站,建网站的八个步骤,公司企业邮箱怎么注册,wordpress网站源码专栏系列文章地址#xff1a;https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标#xff1a; 要对Java线程有整体了解#xff0c;深入认识到里面的一些方法和Object对象方法的区别。认识到Java对象的ObjectMonitor#xff0c;这有助于后面的Synchron…专栏系列文章地址https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标 要对Java线程有整体了解深入认识到里面的一些方法和Object对象方法的区别。认识到Java对象的ObjectMonitor这有助于后面的Synchronized和锁的认识。利用Synchronized wait/notify 完成一道经典的多线程题目实现ABC循环输出。 目录 Java线程Java线程创建new Thread()init方法 Thread 的运行 start() run()线程所需栈空间Java线程的6种状态6种线程状态转换图验证线程的6种状态操作系统定义线程的5种状态附线程的上下文切换Thread Context Switch Thread APIsleepyieldsleep与yield的区别join(线程的join方法)join源码分析 线程的优先级线程ID获取当前线程(Thread.currentThread()) 如何关闭一个线程正常结束run方法执行完成捕获中断信号关闭线程终端间接控制run方法使用volatile开关控制开关控制run方法异常退出进程假死 ObjectObjectMonitorJava线程回顾ObjectMonitor对象ObjectMonitor主要对象成员ObjectWaiterObjectMonitor的基本工作机制 获取锁 ObjectMonitor::enter释放锁 ObjectMonitor::exit Object的wait, notify方法wait java源码notify java源码wait和sleep的区别 实现ABC循环输出 Java线程 Java线程创建 本质都是实现Runnable接口。 百度ai回答 new Thread() class Thread implements Runnable {// 成员变量 /* Java thread status for tools, * initialized to indicate thread not yet started */ private volatile int threadStatus 0;/* The group of this thread */ private ThreadGroup group;/* For autonumbering anonymous threads. */ private static int threadInitNumber; private static synchronized int nextThreadNum() {return threadInitNumber; }// 常见构造方法 public Thread(Runnable target) {init(null, target, Thread- nextThreadNum(), 0); }public Thread(ThreadGroup group, String name) {init(group, null, name, 0); }init方法 一个线程的创建肯定是由另一个线程完成的(线程的父子关系)被创建线程的父线程是创建它的线程 /*** Initializes a Thread.** param g the Thread group* param target the object whose run() method gets called* param name the name of the new Thread* param stackSize the desired stack size for the new thread, or* zero to indicate that this parameter is to be ignored.* param acc the AccessControlContext to inherit, or* AccessController.getContext() if null* param inheritThreadLocals if {code true}, inherit initial values for* inheritable thread-locals from the constructing thread*/ private void init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc,boolean inheritThreadLocals) {if (name null) {throw new NullPointerException(name cannot be null);}this.name name;Thread parent currentThread();SecurityManager security System.getSecurityManager();if (g null) {/* Determine if its an applet or not *//* If there is a security manager, ask the security managerwhat to do. */if (security ! null) {g security.getThreadGroup();}/* If the security doesnt have a strong opinion of the matteruse the parent thread group. */if (g null) {g parent.getThreadGroup();}}/* checkAccess regardless of whether or not threadgroup isexplicitly passed in. */g.checkAccess();/** Do we have the required permissions?*/if (security ! null) {if (isCCLOverridden(getClass())) {security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);}}g.addUnstarted();this.group g;this.daemon parent.isDaemon();this.priority parent.getPriority();if (security null || isCCLOverridden(parent.getClass()))this.contextClassLoader parent.getContextClassLoader();elsethis.contextClassLoader parent.contextClassLoader;this.inheritedAccessControlContext acc ! null ? acc : AccessController.getContext();this.target target;setPriority(priority);if (inheritThreadLocals parent.inheritableThreadLocals ! null)this.inheritableThreadLocals ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);/* Stash the specified stack size in case the VM cares */this.stackSize stackSize;/* Set thread ID */tid nextThreadID(); }Thread 的运行 start() run() run() Override public void run() {if (target ! null) {target.run();} }start() public synchronized void start() {/*** This method is not invoked for the main method thread or system* group threads created/set up by the VM. Any new functionality added* to this method in the future may have to also be added to the VM.** A zero status value corresponds to state NEW.*/if (threadStatus ! 0)throw new IllegalThreadStateException();// 加入到线程组中/* Notify the group that this thread is about to be started* so that it can be added to the groups list of threads* and the groups unstarted count can be decremented. */group.add(this);boolean started false;try {start0();started true;} finally {try {if (!started) {group.threadStartFailed(this);}} catch (Throwable ignore) {/* do nothing. If start0 threw a Throwable thenit will be passed up the call stack */}} }// start0()会新运行一个线程新线程会调用run()方法 private native void start0();需要注意的点 start方法用synchronized修饰为同步方法表示真正的去执行线程虽然为同步方法但不能避免多次调用问题所以用threadStatus来记录线程状态如果线程被多次start调用会抛出异常threadStatus的状态由JVM控制。使用Runnable时主线程无法捕获子线程中的异常状态。线程的异常应在线程内部解决。 区别start()是让另一个新线程开启线程处于可运行状态如果获取到CPU时间片则并执行其中的run方法run()是当前线程直接执行其run方法不产生新线程。run方法一般称为线程的执行单元 when program calls start() method, a new thread is created and code inside run() is executed in new thread.Thread.start() calls the run() method asynchronousl异步的,which changes the state of new Thread to Runnable. call run() method directly no new thread will be created and code inside run() will execute in the current thread directly. native方法start0():调用JVM方法创建一个本地线程并处于可运行状态获取到CPU时间片就能执行run方法 start0() method: is responsible for low processing (stack creation for a thread and allocating thread in processor queue) at this point we have a thread in Ready/Runnable state. start0在linux下本质会进行 pthread_create 的调用 线程所需栈空间 /* * The requested stack size for this thread, or 0 if the creator did * not specify a stack size. It is up to the VM to do whatever it * likes with this number; some VMs will ignore it. */ private long stackSize;操作系统对一个进程的最大内存是有限制的 虚拟机栈是线程私有的即每个线程都会占有指定大小的内存(-Xss默认1M) JVM能创建多少个线程与堆内存栈内存的大小有直接的关系只不过栈内存更明显一些线程数目还与操作系统的一些内核配置有很大的关系生产上要监控线程数量可能会由于bug导致线程数异常增多引发心跳、OutOfMemory告警 举例 32位操作系统的最大寻址空间是2^32个字节≈4G一个32位进程最大可使用内存一般为2G操作系统预留2G; JVM Memory 代表JVM的堆内存占用此处也包含一些JVM堆外内存占用如code-cache、 direct-memory-buffer 、class-compess-space等假设取1.5G,还有一部分必须用于系统dll的加载。假设剩下400MB每个线程栈所需1M那么最多可以创建400个线程 Java线程的6种状态 NEWRUNNABLE(可运行状态运行状态阻塞状态)BLOCKEDWAITINGTIMED WAITINGTERMINATED Thread类源码 /*** A thread state. A thread can be in one of the following states:* ul* li{link #NEW}br* A thread that has not yet started is in this state.* /li* li{link #RUNNABLE}br* A thread executing in the Java virtual machine is in this state.* /li* li{link #BLOCKED}br* A thread that is blocked waiting for a monitor lock* is in this state.* /li* li{link #WAITING}br* A thread that is waiting indefinitely for another thread to* perform a particular action is in this state.* /li* li{link #TIMED_WAITING}br* A thread that is waiting for another thread to perform an action* for up to a specified waiting time is in this state.* /li* li{link #TERMINATED}br* A thread that has exited is in this state.* /li* /ul** p* A thread can be in only one state at a given point in time.* These states are virtual machine states which do not reflect* any operating system thread states.** since 1.5* see #getState*/public enum State {/*** Thread state for a thread which has not yet started.*/NEW,/*** Thread state for a runnable thread. A thread in the runnable* state is executing in the Java virtual machine but it may* be waiting for other resources from the operating system* such as processor.*/RUNNABLE,/*** Thread state for a thread blocked waiting for a monitor lock.* A thread in the blocked state is waiting for a monitor lock* to enter a synchronized block/method or* reenter a synchronized block/method after calling* {link Object#wait() Object.wait}.*/BLOCKED,/*** Thread state for a waiting thread.* A thread is in the waiting state due to calling one of the* following methods:* ul* li{link Object#wait() Object.wait} with no timeout/li* li{link #join() Thread.join} with no timeout/li* li{link LockSupport#park() LockSupport.park}/li* /ul** pA thread in the waiting state is waiting for another thread to* perform a particular action.** For example, a thread that has called ttObject.wait()/tt* on an object is waiting for another thread to call* ttObject.notify()/tt or ttObject.notifyAll()/tt on* that object. A thread that has called ttThread.join()/tt* is waiting for a specified thread to terminate.*/WAITING,/*** Thread state for a waiting thread with a specified waiting time.* A thread is in the timed waiting state due to calling one of* the following methods with a specified positive waiting time:* ul* li{link #sleep Thread.sleep}/li* li{link Object#wait(long) Object.wait} with timeout/li* li{link #join(long) Thread.join} with timeout/li* li{link LockSupport#parkNanos LockSupport.parkNanos}/li* li{link LockSupport#parkUntil LockSupport.parkUntil}/li* /ul*/TIMED_WAITING,/*** Thread state for a terminated thread.* The thread has completed execution.*/TERMINATED;}6种线程状态转换图 阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。 TIMED_WAITING: A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. Thread.sleepObject.wait with timeoutThread.join with timeoutLockSupport.parkNanosLockSupport.parkUntil 验证线程的6种状态 public class Main {public static void main(String[] args) throws Exception{Thread t1 new Thread(()-{System.out.println(t1 running);},t1);Thread t2 new Thread(()-{while (true){}},t2);t2.start();Thread t3 new Thread(()-{// do sth // System.out.println(t3 running);}, t3);t3.start();Thread t4 new Thread(()-{synchronized (Main.class){try{// 有限时间的等待TimeUnit.SECONDS.sleep(100); // TIMED_WAITING}catch (Exception e){e.printStackTrace();}}}, t4);t4.start();Thread t5 new Thread(()-{try{// 无限时间的等待t2.join(); // WAITING}catch (Exception e){e.printStackTrace();}}, t5);t5.start();Thread t6 new Thread(()-{synchronized (Main.class){ // 竞争锁竞争不到BLOCKEDtry{TimeUnit.SECONDS.sleep(100);}catch (Exception e){e.printStackTrace();}}}, t6);t6.start();TimeUnit.SECONDS.sleep(1);System.out.println(t1 status: t1.getState());System.out.println(t2 status: t2.getState());System.out.println(t3 status: t3.getState());System.out.println(t4 status: t4.getState());System.out.println(t5 status: t5.getState());System.out.println(t6 status: t6.getState());}}输出 t1 status:NEW t2 status:RUNNABLE t3 status:TERMINATED t4 status:TIMED_WAITING // 有限时间等待如sleep特定时间 t5 status:WAITING // 无限等待条件如join t6 status:BLOCKED // 阻塞如抢锁抢不到操作系统定义线程的5种状态 初始状态new可运行状态/就绪状态与操作系统关联有了CPU时间片就可以运行起来准备就绪中运行状态获取到CPU时间片则在运行中如果CPU时间片用完则会变成[可运行状态]阻塞状态等待/阻塞/睡眠操作系统不考虑给这种状态线程分配CPU时间片唤醒后变成[可运行状态]终止状态结束 附线程的上下文切换Thread Context Switch 由于某些原因CPU不执行当前线程转而去执行其它线程 当前线程的CPU时间片用完垃圾回收STW有比该线程更高优先级的线程需要运行线程调用了sleep,yield,wait,join,park,synchronized,lock等方法导致等待/阻塞等 当Context Switch发生时需要有操作系统保存当前线程的状态并恢复另一个线程的状态每个线程都有一个程序计数器Program Counter Register它的作用是记住下一条JVM指令的地址这个程序计数器是线程独有的 状态包括程序计数器虚拟机栈中每个线程栈帧的信息如局部变量表、动态链接、操作数栈、返回地址等Context Switch频繁发生会影响性能 Thread API sleep public static native void sleep(long millis) throws InterruptedExceptionpublic static void sleep(long millis, int nanos) hrows InterruptedException// 人性化设置休眠时间的sleep package java.util.concurrentTimeUnitsleep休眠不会放弃monitor锁的所有权各个线程的休眠不会相互影响sleep只会导致当前线程休眠 sleep 底层原理 挂起进程或线程并修改其运行状态可以被中断用sleep()提供的参数来设置一个定时器。可变定时器(variable timer)一般在硬件层面是通过一个固定的时钟和计数器来实现的每经过一个时钟周期将计数器递减当计数器的值为0时产生中断。内核注册一个定时器后可以在一段时间后收到中断。当时间结束定时器会触发内核收到中断后修改进程或线程的运行状态。例如线程会被标志为就绪而进入就绪队列等待调度。 yield vt.屈服投降; 生产; 获利; 不再反对; vi.放弃屈服; 生利; 退让退位; n.产量产额; 投资的收益; 屈服击穿; 产品;启发式的方式提醒调度器愿意放弃当前CPU资源如果CPU资源不紧张则会忽略这种提醒 /** * A hint to the scheduler that the current thread is willing to yield * its current use of a processor. The scheduler is free to ignore this * hint. * * p Yield is a heuristic attempt to improve relative progression * between threads that would otherwise over-utilise a CPU. Its use * should be combined with detailed profiling and benchmarking to * ensure that it actually has the desired effect. * * p It is rarely appropriate to use this method. It may be useful * for debugging or testing purposes, where it may help to reproduce * bugs due to race conditions. It may also be useful when designing * concurrency control constructs such as the ones in the * {link java.util.concurrent.locks} package. */ public static native void yield();测试程序 class MyThread extends Thread {int id;public MyThread() {}public MyThread(int _id) {id _id;}Overridepublic void run() {if(id 0){Thread.yield();}System.out.println(id: id);} }public class Main {static void test(){MyThread[] ts new MyThread[2];for(int i0;its.length;i){ts[i] new MyThread(i);}for(int i0;its.length;i){ts[i].start();}}public static void main(String[] args) throws Exception {test();System.out.println(Main thread finished);} }输出顺序无规律,如下是其中的一次输出所以并不总是直接让出CPU id:0 id:1 Main thread finishedsleep与yield的区别 yield会使RUNNING状态的线程进入Runnable状态前提是如果CPU调度器没有忽略这个提示的话一个线程sleep另一个线程调用interrupt会捕获到中断信号而yield则不会 join(线程的join方法) 与sleep一样也是一个可中断的方法底层是调用对象的wait方法 在线程B中执行A.join()会使得当前线程B进入等待直到线程A结束生命周期或者到达给定的时间在此期间B线程是处于Blocked的 join方法必须在线程start方法调用之后调用才有意义。这个也很容易理解如果一个线程都没有start那它也就无法同步了。因为执行完start方法才会创建线程。 join源码分析 判断线程是否alive,否则一直wait() public final void join() throws InterruptedException {join(0); }public final synchronized void join(long millis)throws InterruptedException {long base System.currentTimeMillis();long now 0;if (millis 0) {throw new IllegalArgumentException(timeout value is negative);}if (millis 0) {while (isAlive()) {wait(0);}} else {while (isAlive()) {long delay millis - now;if (delay 0) {break;}wait(delay);now System.currentTimeMillis() - base;}}}线程的优先级 理论上线程优先级高的会获得优先被CPU调度的机会但实际上这也是个hint操作 如果CPU比较忙设置优先级可能会获得更多的CPU时间片但是CPU闲时, 优先级的高低几乎不会有任何作用 对于root用户它会hint操作系统你想要设置的优先级别否则它会被忽略 /*** Changes the priority of this thread.* p* First the codecheckAccess/code method of this thread is called* with no arguments. This may result in throwing a* codeSecurityException/code.* p* Otherwise, the priority of this thread is set to the smaller of* the specified codenewPriority/code and the maximum permitted* priority of the threads thread group.** param newPriority priority to set this thread to* exception IllegalArgumentException If the priority is not in the* range codeMIN_PRIORITY/code to* codeMAX_PRIORITY/code.* exception SecurityException if the current thread cannot modify* this thread.* see #getPriority* see #checkAccess()* see #getThreadGroup()* see #MAX_PRIORITY* see #MIN_PRIORITY* see ThreadGroup#getMaxPriority()*/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();}setPriority0(priority newPriority);}}线程ID 线程的ID在整个JVM进程中都会是唯一的并且是从0开始逐次增加 /*** Returns the identifier of this Thread. The thread ID is a positive* ttlong/tt number generated when this thread was created.* The thread ID is unique and remains unchanged during its lifetime.* When a thread is terminated, this thread ID may be reused.** return this threads ID.* since 1.5*/public long getId() {return tid;}获取当前线程(Thread.currentThread()) class MyThread extends Thread {Overridepublic void run() {Thread thread1 Thread.currentThread();// trueSystem.out.println( this thread1);} }如何关闭一个线程 注stop()方法以及作废因为如果强制让线程停止有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了解锁导致数据得不到同步的处理出现数据不一致的问题。 正常结束run方法执行完成 捕获中断信号关闭线程终端间接控制run方法 interrupt是Thread类的实例方法它的主要作用是给目标线程发送一个通知 第一种是打断正在运行的线程。如下所示主线程休眠100ms后中断t1线程并将t1线程的中断标志设置为true。当线程发现自己的打断标志为true时就自动退出 第二种情况是打断正在休眠的线程比如目标线程调用了sleep方法而处于阻塞状态这时候如果打断他就会抛出InterruptedException异常。 使用volatile开关控制开关控制run方法 public class Main {static class Mythread extends Thread{private volatile boolean close false;Overridepublic void run() {System.out.println(start);while(!close !isInterrupted()){System.out.println(running...);}System.out.println(end);}public void close(){this.close true;this.interrupt();}}public static void main(String[] args) throws Exception{Mythread mythread new Mythread();mythread.start();TimeUnit.SECONDS.sleep(1);mythread.close();System.out.println(main end);} }异常退出 进程假死 Object ObjectMonitor Monitors – The Basic Idea of Java Synchronization Java线程回顾 open jdk源码地址https://github.com/openjdk/jdk Java线程Java Thread是由Java虚拟机JVM创建和管理的它是Java程序中最基本的执行单元。Java线程和操作系统线程OS Thread是不同的概念。在HotSpot中Java线程实际上是由JavaThread类表示的。JavaThread类是Thread类的子类它继承了Thread类的一些属性和方法并添加了一些额外的属性和方法用于实现Java线程的特性如线程状态、调用栈、异常处理等。JavaThread类的实例代表了一个Java线程。 而OS Thread类则是一个抽象类它封装了HotSpot对操作系统线程的抽象和管理如线程ID、优先级、调度等。Java Thread类包含了一个OS Thread类的成员变量用于表示Java线程所对应的操作系统线程。Java线程和操作系统线程之间的关系是一对一的。每个Java线程都会有一个对应的操作系统线程来执行它的任务。因此Java线程的生命周期受操作系统线程的调度和管理。 在/hotspot/src/share/vm/runtime/thread.cpp中Thread对象内部包含了该线程的状态、调度优先级、执行栈、栈帧、持有的锁等信息。 ObjectMonitor对象 每个Java对象中都具有一个一个ObjectMonitor对象。在Java中每个对象都可以用作锁来同步多个线程的访问。当线程获取某个对象的锁时它实际上是获取该对象关联的ObjectMonitor对象的锁。因此每个对象在Java中都有一个与之关联的ObjectMonitor对象来控制线程对该对象的访问。 ObjectMonitor主要对象成员 _object 指向被监视的对象即 Java 层面的对象_owner 指向持有ObjectMonitor对象的线程地址。_WaitSet 一个 ObjectWaiter 对象的链表用于存储被阻塞的线程由于 wait() 或 join() 等待 monitor 的状态_EntryList 一个 ObjectWaiter 对象的链表用于存储被阻塞(block住)的线程等待 monitor 进入_recursions 锁的重入次数。_count 线程获取锁的次数。 ObjectWaiter ObjectWaiter是一个用于等待唤醒的数据结构。在Java中Object.wait() 方法调用后线程会被挂起直到另一个线程调用Object.notify() 或 Object.notifyAll() 方法或者线程等待时间到期或者线程被中断才会被唤醒。当一个线程调用Object.wait() 方法后会创建一个ObjectWaiter对象该对象会被加入到等待队列中。当另一个线程调用Object.notify() 或 Object.notifyAll() 方法时会从等待队列中取出一个或多个ObjectWaiter对象并将它们加入到可用队列中以便在下一次竞争锁时唤醒这些线程。 ObjectMonitor的基本工作机制 当多个线程同时访问一段同步代码时首先会进入 _EntryList 队列中。 当某个线程获取到对象的Monitor后进入临界区域并把Monitor中的 _owner 变量设置为当前线程同时Monitor中的计数器 _count 加1。即获得对象锁。 若持有Monitor的线程调用 wait() 方法将释放当前持有的Monitor_owner变量恢复为null_count自减1同时该线程进入 _WaitSet 集合中等待被唤醒。 在_WaitSet 集合中的线程会被再次放到_EntryList 队列中重新竞争获取锁。 若当前线程执行完毕也将释放Monitor并复位变量的值以便其它线程进入获取锁 获取锁 ObjectMonitor::enter 首先如果没有线程使用这个锁则直接获取锁若有线程是会尝试通过原子操作来将当前线程设置成此对象的监视器锁的持有者。 如果原来的持有者是 null则当前线程成功获取到了锁。如果原来的持有者是当前线程则说明当前线程已经持有该锁并且将计数器递增如果原来的持有者是其它线程则说明存在多线程竞争代码会将当前线程阻塞并且进入一个等待队列中等待被唤醒。如果开启了自旋锁则会尝试自旋一段时间以避免多线程竞争导致的阻塞开销过大。如果自旋后仍未获得锁则当前线程将进入一个等待队列中并且设置自己为队列的尾部。等待队列中的线程按照LIFO避免头部饥饿的顺序进行排队。当持有者释放锁时队列头的线程将被唤醒并尝试重新获取锁。 释放锁 ObjectMonitor::exit 用于释放当前线程占用的 monitor 并唤醒等待该 monitor 的其它线程 检查当前线程是否持有该锁。如果没有持有该锁会对其进行修复假设线程实际上持有该锁但是由于某些原因owner字段没有正确更新或抛出异常如果线程没有正确地获取该锁即不在_owner字段中。如果当前线程是多次重入该锁将计数器减1并直接返回。这是因为线程实际上仍然持有该锁。检查是否有其它线程等待该锁。如果没有等待线程直接将_owner字段设置为null并返回。如果有等待线程则释放该锁并使等待线程之一成为新的owner。如果等待线程中有线程使用了公平自旋Ticket Spinlock算法则使用该算法来释放该锁。否则使用等待队列或Cache Exclusive QueueCXQ算法来释放该锁。这些算法可以更有效地处理多个线程对同一对象锁的竞争从而提高性能。 Object的wait, notify方法 参考文档 https://www.baeldung.com/java-wait-notify Simply put, when we call wait() – this forces the current thread to wait until some other thread invokes notify() or notifyAll() on the same object.(当调用wait()后当前线程将等待其它线程调用notity()) wait java源码 public final void wait() throws InterruptedException {wait(0); }public final native void wait(long timeout) throws InterruptedException;将当前线程封装成ObjectWaiter对象node通过ObjectMonitor::AddWaiter方法将node添加到_WaitSet列表中通过ObjectMonitor::exit方法释放当前的ObjectMonitor对象这样其它竞争线程就可以获取该ObjectMonitor对象。 notify java源码 public final native void notify();在Java中每一个对象都可以成为一个监视器(Monitor)该Monitor有一个锁(lock), 一个等待队列(WaitingSet阻塞状态等待被唤醒不占用CPU), 一个入口队列(EntryList要去竞争获取锁).wait进入_waitSet等待中(底层通过执行thread_ParkEvent-park来挂起线程)等待被唤醒不会占用CPUwait被唤醒后不是直接执行而是进入_EntryList(Entrylist是没有获取到锁的一个Blocking状态要继续竞争锁)去竞争monitor来获得机会去执行 wait和sleep的区别 wait()方法属于Object类sleep()属于Thread类 wait()方法让自己让出锁资源进入等待池等待直接让出CPU后续要竞争monitor锁sleep是继续占用锁(依赖于系统时钟和CPU调度机制)处于阻塞状态也会让出CPU sleep()必须指定时间wait()可以指定时间也可以不指定sleep()时间到线程处于阻塞或可运行状态 wait()方法会释放持有的锁调用notify(),notifyAll()方法来唤醒线程sleep方法不会释放持有的锁设置sleep的时间是确定的会按时执行的超时或者interrupt()能唤醒 wait()方法只能在同步方法或同步代码块中调用否则会报illegalMonitorStateException异常如果没有设定时间使用notify()来唤醒而sleep()能在任何地方调用 wait()方法只能在同步方法或同步代码块中调用原因是避免CPU切换到其它线程而其它线程又提前执行了notify方法那这样就达不到我们的预期先wait再由其它线程来notify,所以需要一个同步锁来保护。 wait是对象的方法java锁是对象级别的而不是线程级别的同步代码块中使用对象锁来实现互斥效果 实现ABC循环输出 import java.util.concurrent.TimeUnit;public class Main {static Object object new Object();static int count 0; // 先打印A则初始化为0static int N 3; // ABC打印多少次public static void main(String[] args) throws Exception {Thread threadA new Thread(()-{synchronized (object) {for (int i 0; i N; i) {while (count % 3 ! 0) {try{object.wait();}catch (InterruptedException e){}}System.out.print(A);count;object.notifyAll();}}});Thread threadB new Thread(()-{synchronized (object) {for (int i 0; i N; i) {while (count % 3 ! 1) {try{object.wait();}catch (InterruptedException e){}}System.out.print(B);count;object.notifyAll();}}});Thread threadC new Thread(()-{synchronized (object) {for (int i 0; i N; i) {while (count % 3 ! 2) {try{object.wait();}catch (InterruptedException e){}}System.out.print(C);count;object.notifyAll();}}});threadA.start();TimeUnit.SECONDS.sleep(1);threadB.start();TimeUnit.SECONDS.sleep(1);threadC.start();threadA.join();threadB.join();threadC.join();System.out.println();} }代码分析 线程在wait()所在的代码行处暂停执行进入wait队列并释放锁直到接到通知恢复执行或中断。wait释放锁则其它线程有机会拿到锁完成自己的执行notifyAll使所有正在等待队列中线程退出等待队列进入就绪状态。
http://www.zqtcl.cn/news/561821/

相关文章:

  • 淘宝导购网站模版上海网站推广软件
  • 做影视网站引流湖北响应式网站建设费用
  • 网站统计cnzz网站空间有哪些
  • 泉州微信网站开发公司wordpress头像解决
  • 湛江网站建设皆选小罗24专业网站建设 福田
  • 厦门哪些做鲜花的网站门户网站开发设计报告
  • asp.net网站设计分工天津网站开发贴吧
  • 做多语言网站教程南宁vi设计公司
  • 百度联盟 网站备案wordpress 吾爱破解
  • 山西省建设厅网站首页网络营销推广为什么效果不好
  • 建材做网站好吗长沙做网站微联讯点不错
  • 建设小型网站分类门户网站系统
  • 文化馆网站数字化建设介绍138ip地址查询网站
  • 卖汽车的网站怎么做的建设服装网站的论文
  • 网络推广哪个网站好网站建设最低多少钱
  • 怎么在自己电脑做网站北京赛车网站开发
  • 门户网站内容wordpress上下页
  • 长安做英文网站营销型网站搭建
  • 网站开发交接清单seo排名优化方法
  • 各学院二级网站建设通报wordpress注册评论
  • 南通公司做网站无人在线完整免费高清观看
  • 廊坊网站推广局域网网站建设的步骤过程
  • 如何在工信部网站注册简易网页设计代码
  • 做石油系统的公司网站做艺术品展览的网站
  • 枣庄公司网站建设珠海蓝迪装饰设计工程有限公司
  • 广州企业网站营销电话成都网站建设制作设计
  • 求个网站带图片素材域名及密码登录域名管理网站
  • 文交所网站开发wordpress页面编辑插件
  • 丹徒网站建设价格做矿产公司的网站
  • 北京的制作网站的公司在哪里软件程序员