Thread线程从创建、运行到结束总是处于下面五个状态之一:新建状态、就绪状态、运行状态、阻塞状态及死亡状态。
内存的原子性、可见性 & 有序性;
-- Thread.start()与Thread.run()的区别
1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。 在子线程中运行,即多线程;
2.run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。在主线程中跑。
> 线程
Thread类也是Runnable接口的子类;Thread运行在父类的run方法中,Runnable运行在实现Runnable接口的子类对象run方法中。
Java 多线程实现接口Runnable和继承Thread区别-- http://blog.sina.com.cn/s/blog_9cbb6a210102ux44.html
java线程系列---Runnable和Thread的区别、线程同步-- http://blog.csdn.net/guoxiaolongonly/article/details/50717574
-- 多线程实现的两种方式,extends Thread 或 implements Runnable
1、继承Thread:extends Thread,子类重写父类的run(),调用Thread.start()
2、实现Runnable接口:implements Runnable,Thread的构造函数中传入了Runnable引用,调用Thread.start()
-- 多线程实现
1、继承Thread类创建线程,Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。
public class MyThread extends Thread {
public void run() {
System.out.println("MyThread.run()");
}
}
2、实现Runnable接口创建线程,如果自己的类已经extends另一个类,就无法直接extends Thread,此时,可以实现一个Runnable接口,如下:
public class MyThread extends OtherClass implements Runnable {
public void run() {
System.out.println("MyThread.run()");
}
}
3、实现Callable接口通过FutureTask包装器来创建Thread线程
4、使用ExecutorService、Callable、Future实现有返回结果的线程
> wait,await,notify,join,yield,signal
有三个线程T1 T2 T3,如何保证他们按顺序执行,使用join()方法。
java.util.concurrent包(3)-线程间通信wait/notify和await/signal- https://blog.csdn.net/woshixuye/article/details/28283289
Java 并发--- 线程间协作的两种方式:wait、notify、notifyAll和Condition-https://www.cnblogs.com/hesier/p/5930163.html
Java线程中sleep()、wait()和notify()和notifyAll()、suspend和resume()、yield()、join()、interrupt()的用法和区别 - http://zheng12tian.iteye.com/blog/1233638
java 线程同步的那些事: yield(), sleep(), wait(), await(), signal(), sginalAll()- https://blog.csdn.net/bigtree_3721/article/details/42001149
java多线程同步代码块wait(),notify()和notifyAll()- http://dacoolbaby.iteye.com/blog/2105721
Thread.join()在AsyncTask中的妙用:http://melord.iteye.com/blog/1555551
-- sleep和yield,await与wait
调用sleep和yield的时候不释放当前线程所获得的锁,但是调用await/wait的时候却释放了其获取的锁并阻塞等待。
# sleep让线程阻塞,且在指定的时间之内都不会执行,时间到了之后恢复到就绪状态,也不一定被立即调度执行,sleep()不释放同步锁。sleep()可以将一个线程睡眠,参数可以指定一个时间。
# yield只是让当前对象回到就绪状态,还是有可能马上被再次被调用执行。
# await/wait,它会一直阻塞在条件队列之上,之后某个线程调用对应的notify/signal方法,才会使得await/wait的线程回到就绪状态,也是不一定立即执行。wait()释放同步锁。wait()可以将一个线程挂起,直到超时或者该线程被唤醒。wait方法依赖于同步。
yield和sleep方法都是Thread类的,await方法是Condition显示条件队列的。
yield和sleep方法可以放在线程中的任意位置,而await/wait方法必须放在同步块里面,否则会产生运行时异常。
wait()、notify()和notifyAll()是Object类中的方法。void notify(): 唤醒一个正在等待该对象的线程。void notifyAll(): 唤醒所有正在等待该对象的线程。wait()、notify()和notifyAll()一般是跟synchronized配合一起使用,这些方法都是Object类提供的。
-- 线程之间通信:join/wait/notify/notifyAll方法
wait()方法会释放CPU执行权 和 占有的锁。
sleep(long)方法仅释放CPU使用权,锁仍然占用;线程被放入超时等待队列,与yield相比,它会使线程较长时间得不到运行。
yield()方法仅释放CPU执行权,锁仍然占用,线程会被放入就绪队列,会在短时间内再次执行。
wait和notify必须配套使用,即必须使用同一把锁调用;
wait和notify必须放在一个同步块中
调用wait和notify的对象必须是他们所处同步块的锁对象。
-- sleep和wait的区别有:
1,这两个方法来自不同的类分别是Thread和Object
2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在
任何地方使用
synchronized(x){
x.notify()
//或者wait()
}
4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
5.sleep方法只是暂时让出CPU的执行权,并不释放锁。而wait方法则需要释放锁。
-- notify()与notifyAll()的区别:
-- notify():
唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。
-- notifyAll():
唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。
> Conditon
Conditon中的await()对应Object的wait();
Condition中的signal()对应Object的notify();
Condition中的signalAll()对应Object的notifyAll()。
本文详细介绍了Java线程的创建方式、状态转换、线程间的通信方法等核心概念。包括Thread类与Runnable接口的区别,以及wait、notify等同步方法的正确使用。

799

被折叠的 条评论
为什么被折叠?



