------- android培训、java培训、java学习型技术博客、期待与您交流! ----------
知识点
01)线程间通信——示例代码
![](https://img-my.csdn.net/uploads/201303/18/1363588199_2608.jpg)
public class InputOutputThread {
public static void main(String[] args) {
Res r = new Res();//资源
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 Res{
String name;
String an;
}
class Input implements Runnable{
private Res r;
Input(Res r){
this.r = r;
}
public void run(){
int x = 0;
while(true){
if (x == 0){
r.name = "汤姆";
r.an = "猫咪";
}else{
r.name = "杰瑞";
r.an = "老鼠";
}
x = (x + 1) % 2;
}
}
}
class Output implements Runnable{
private Res r;
Output(Res r){
this.r = r;
}
public void run(){
while(true)
System.out.println(r.name + "是: " + r.an);
}
}//陷入死循环中~
02)解决安全问题。
public class InputOutputThread_2 {
public static void main(String[] args) {
Res_2 r = new Res_2();//资源
Input_2 in = new Input_2(r);
Output_2 out = new Output_2(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
class Res_2{
String name;
String an;
}
class Input_2 implements Runnable{
private Res_2 r;
Input_2(Res_2 r){
this.r = r;
}
public void run(){
int x = 0;
while(true){
synchronized(r){//同一个锁。
if (x == 0){
r.name = "汤姆";
r.an = ".猫.咪.";
}else{
r.name = "杰瑞";
r.an = "老...鼠";
}
x = (x + 1) % 2;
}
}
}
}
class Output_2 implements Runnable{
private Res_2 r;
Output_2(Res_2 r){
this.r = r;
}
public void run(){
while(true)
synchronized(r){//同一个锁。
System.out.println(r.name + "是: " + r.an);
}
}
}
03)等待唤醒机制
/*
* 等待唤醒机制。
*
* wait();
* notify();
* notifyAll();
* 都使用在同步中,因为要对持有监视器(锁)的线程进行操作。
* 所以要使用在同步中,因为只有同步才具有锁。
*
* 为什么这些操作线程的方法要定义在Object类中呢?
* 因为这些方法在操作同步中线程时,都必须要标识它们所操作线程所持有的锁。
* 只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒,不可以对不同锁上的notify唤醒。
* 也就是等待和唤醒必须是在同一个锁内。
* 而锁可以是任意对象,所以可以被任意对象调用的方法就定义在Object类中。
*/
public class InputOutputThread_3 {
public static void main(String[] args) {
Res_3 r = new Res_3();//资源
Input_3 in = new Input_3(r);
Output_3 out = new Output_3(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
class Res_3{
String name;
String an;
boolean flag = false;
}
class Input_3 implements Runnable{
private Res_3 r;
Input_3(Res_3 r){
this.r = r;
}
public void run(){
int x = 0;
while(true){
synchronized(r){//同一个锁。
if (r.flag)//如果为真,等待。
try{r.wait();}catch(Exception e){}
if (x == 0){
r.name = "汤姆";
r.an = ".猫.咪.";
}else{
r.name = "杰瑞";
r.an = "老...鼠";
}
x = (x + 1) % 2;
r.flag = true;//将flag设置为真。
r.notify();//唤醒另外一个线程。
}
}
}
}
class Output_3 implements Runnable{
private Res_3 r;
Output_3(Res_3 r){
this.r = r;
}
public void run(){
while(true){
synchronized(r){//同一个锁。
if (!r.flag)//如果为假,等待。
try{r.wait();}catch(Exception e){}
System.out.println(r.name + "是: " + r.an);
r.flag = false;//将falg设置为false。
r.notify();//唤醒另外一个线程。
}
}
}
}
04)代码优化
/*
* 代码的优化。
*/
public class InputOutputYouHua {
public static void main(String[] args) {
ResY r = new ResY();//资源
new Thread(new InputY(r)).start();
new Thread(new OutputY(r)).start();
}
}
class ResY{
String name;
String an;
boolean flag = false;
public synchronized void set(String name, String an){
if (flag)
try{this.wait();}catch(Exception e){}
this.name = name;
this.an = an;
this.flag = true;//将flag设置为真。
this.notify();//唤醒另外一个线程。
}
public synchronized void out(){
if (!flag)
try{this.wait();}catch(Exception e){}
System.out.println(name + "是: " + an);
this.flag = false;//将flag设置为真。
this.notify();//唤醒另外一个线程。
}
}
class InputY implements Runnable{
private ResY r;
InputY(ResY r){
this.r = r;
}
public void run(){
int x = 0;
while(true){
if (x == 0)
r.set("汤姆", ".猫.咪.");
else
r.set("杰瑞", "老...鼠");
x = (x + 1) % 2;
}
}
}
class OutputY implements Runnable{
private ResY r;
OutputY(ResY r){
this.r = r;
}
public void run(){
while(true)
r.out();
}
}
05)线程中通信——生产者消费
/*
* 对于多个生产者和消费者。
* 为什么要定义while判断标记。
* 原因:需要让被唤醒的线程再一次判断标记。
*
* 为什么定义notifyAll();
* 因为需要唤醒对方的线程。
* 因为只有notify()的话,容易只唤醒本方线程的情况。导致程序中的所有线程都等待。
*/
public class PrdCemDemo {
public static void main(String[] args) {
Resource r = new Resource();//共享资源
new Thread(new Producer(r)).start();//生产线程0
new Thread(new Producer(r)).start();//生产线程1
new Thread(new Consumer(r)).start();//消费线程2
new Thread(new Consumer(r)).start();//消费线程3
}
}
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(Exception e){
}
this.name = name + "----" + count++;
System.out.println(Thread.currentThread().getName() + "...生产者" + this.name);
flag = true;
this.notifyAll();
}
public synchronized void out(){//出售商品
while (!flag)
try{
this.wait();
}catch(Exception e){
}
System.out.println(Thread.currentThread().getName() + "...消费者..." + this.name);
flag = false;
this.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();
}
}
}
运行结果如下图所示:
![](https://img-my.csdn.net/uploads/201303/18/1363604116_6761.jpg)
06)生产消费者升级版(JDK1.5版本开始之后)
/*
* 从JDK1.5版本开始,提供了多线程的解决方案。
* 将同步synchronzied替换成现有的Lock方案。
* 将Object中的wait、notify、notifyAll,替换成了Condition对象。
* 该对象可以Lock锁,进行获取。
*/
public class PrdCemSuperDemo {
public static void main(String[] args) {
ResourceSup r = new ResourceSup();//共享资源
new Thread(new ProducerSup(r)).start();//生产线程0
new Thread(new ProducerSup(r)).start();//生产线程1
new Thread(new ConsumerSup(r)).start();//消费线程2
new Thread(new ConsumerSup(r)).start();//消费线程3
}
}
class ResourceSup{
private String name;
private int count = 1;
private boolean flag = false;
private Lock lock = new ReentrantLock();
private Condition con_c = lock.newCondition();//生产者标记
private Condition con_p = lock.newCondition();//消费者标记
public void set(String name) throws InterruptedException{//生产商品
lock.lock();//获取锁。
try{
while (flag)
con_c.await();//生产者线程等待。
this.name = name + "----" + count++;
System.out.println(Thread.currentThread().getName() + "...生产者" + this.name);
flag = true;
con_p.signal();//唤醒消费者线程。
}finally{
lock.unlock();//释放锁
}
}
public void out() throws InterruptedException{//出售商品
lock.lock();//获取锁
try{
while (!flag)
con_p.await();//消费者线程等待。
System.out.println(Thread.currentThread().getName() + "...消费者..." + this.name);
flag = false;
con_c.signal();//唤醒生产者线程。
}finally{
lock.unlock();//释放锁。
}
}
}
class ProducerSup implements Runnable{
private ResourceSup r;
ProducerSup(ResourceSup r){
this.r = r;
}
public void run(){
while(true){
try{
r.set("+商品+");
}catch(InterruptedException e){
}
}
}
}
class ConsumerSup implements Runnable{
private ResourceSup r;
ConsumerSup(ResourceSup r){
this.r = r;
}
public void run(){
while(true){
try{
r.out();
}catch(InterruptedException e){
}
}
}
}
07)停止线程
/*
* stop方法以及过时。
* 如果停止线程?
* 只有一种方法,run方法结束。
* 开启多线程运行,运行代码通常都是循环结构的,只要控制住循环,就可以让run方法结束,也就是线程结束。
*
* 特殊情况:当线程处于冻结状态,就不会读取到标记,那么线程就不会结束。
*
* 当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结状态进行清除。
* 强制让线程恢复到运行状态,这样就可以操作标记让线程结束。
* Thread提供了该方法:interrupt()
*/
public class StopThreadDemo {
public static void main(String[] args) {
StopThread st = new StopThread();
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
int num = 0;
while(true){
if(num++ == 60){
// st.ChangeFlag();
t1.interrupt();//强制清除状态。
t2.interrupt();
break;
}
System.out.println(Thread.currentThread().getName() + "...." + num);
}
}
}
class StopThread implements Runnable{
private boolean flag = true;
public synchronized void run(){
while(flag){
try{
wait();
}catch(InterruptedException e){
System.out.println(Thread.currentThread().getName() + " ... InterruptedException");
flag = false;
}
System.out.println(Thread.currentThread().getName() + " ... run");
}
}
// public void ChangeFlag(){
// flag = false;
// }
}
08)守护线程
/*
* 设置守护线程:setDaemon(true);也就是后台线程。
* 注意:必须在开启线程之前设置。
*/
public class SetDaemonThreadDemo {
public static void main(String[] args) {
SetDaemonThread st = new SetDaemonThread();
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
t1.setDaemon(true);//设置为守护线程,也就是后台线程。
t2.setDaemon(true);//注意:必须在开启线程之前设置。
t1.start();
t2.start();
int num = 0;
while(true){
if(num++ == 60){
// t1.interrupt();//强制清除状态。
// t2.interrupt();
break;
}
System.out.println(Thread.currentThread().getName() + "...." + num);
}
}
}
class SetDaemonThread implements Runnable{
private boolean flag = true;
public void run(){
while(flag){
System.out.println(Thread.currentThread().getName() + " ... run");
}
}
}
09)join方法
/*
* Join:
* 当t2线程执行到了t1线程的.join方法时,t2就会等待,等t1线程执行完,t2才会执行。
* join用来临时加入线程执行。
*/
public class JoinThreadDemo {
public static void main(String[] args) throws InterruptedException{
JoinThread jt = new JoinThread();
Thread t1 = new Thread(jt);
Thread t2 = new Thread(jt);
t1.start();
t1.join();//t1申请cup执行权。主线程main放弃执行权,变更为冻结状态。
t2.start();
for(int i = 0; i < 80; i++){
System.out.println("Main..." + i);
}
}
}
class JoinThread implements Runnable{
public void run(){
for(int i = 0; i < 70; i++){
System.out.println(Thread.currentThread().getName() + "..." + i);
}
}
}
10) 优先级
public class ToStringThreadDemo {
public static void main(String[] args) throws InterruptedException{
ToStringThread jt = new ToStringThread();
Thread t1 = new Thread(jt);
Thread t2 = new Thread(jt);
t1.start();
// t1.setPriority(Thread.MAX_PRIORITY);//设置优先级
t2.start();
for(int i = 0; i < 80; i++){
System.out.println(Thread.currentThread().toString() + "Main..." + i);
}
}
}
class ToStringThread implements Runnable{
public void run(){
for(int i = 0; i < 70; i++){
System.out.println(Thread.currentThread().toString() + "..." + i);
Thread.yield();//暂停当前正在执行的线程对象,并执行其他线程。
}
}
}
附言:我是Java新人,如有错误的地方请指出。
每天学习一点点,纠错一点点,进步很大点。