多线程间的通信:
//多线程间通信。
//功能:
// 1.Input类向资源中写入信息;
// 2.Output类从资源中读取信息;
//共享资源类;
class Res{
String name;
String sex;
}
//实现Runnable接口的类;
class Input implements Runnable{
//定义共享资源的类参数,然后传递给构造函数;
//目的是操作同一个共享资源的对象;
Res r;
Input(Res r){
this.r=r;
}
//重写Runnable接口的run方法;
public void run(){
int x=0;
while(true){
//上锁;
//由于操作同一资源,需和Output上的锁一致。
//这样一旦上锁,另外一个操做共享资源的函数就不能操作共享数据。
synchronized(Input.class){
if(x==0){
r.name="---a";
r.sex="boy";
}
else{
r.name="+++b";
r.sex="girl";
}
x=(x+1)%2;
}
}
}
}
class Output implements Runnable{
Res r;
Output(Res r){
this.r=r;
}
public void run(){
while(true){
//上锁;
//由于操作同一资源,需和Iuput上的锁一致。
//这样一旦上锁,另外一个操做共享资源的函数就不能操作共享数据。
synchronized(Input.class){
System.out.println(r.name+"......"+r.sex);
}
}
}
}
class InputOutputDemo{
public static void main(String[] args){
Res r=new Res();
//使两个线程操作同一对象。
Output out=new Output(r);
Input in=new Input(r);
//构建两个线程,虽然是两个线程,但操作的是同一个对象中的共享资源。
Thread t1=new Thread(in);
Thread t2=new Thread(out);
//启动线程。
t1.start();
t2.start();
}
}
多线程的唤醒等待机制
//多线程间通信。
//功能:
// 1.Input类向资源中写入信息;
// 2.Output类从资源中读取信息;
//共享资源类;
class Res{
String name;
String sex;
//定义读写操作完成标识。flag为真:有未读的数据,flag为假:数据已读
boolean flag=false;
}
//实现Runnable接口的类;
class Input implements Runnable{
//定义共享资源的类参数,然后传递给构造函数;
//目的是操作同一个共享资源的对象;
Res r;
Input(Res r){
this.r=r;
}
//重写Runnable接口的run方法;
public void run(){
int x=0;
while(true){
//上锁;
//由于操作同一资源,需和Output上的锁一致。
//这样一旦上锁,另外一个操做共享资源的函数就不能操作共享数据。
synchronized(r){
if(r.flag) //若数据未读则等待。wait()定义时抛出异常。
//调用wait方法将自身操作挂起,直到同一个对象上的锁以某种方式将其改变改变,并调用notify方法通知该代码块改变已经完成。
try{r.wait();}catch(Exception e){}
if(x==0){
r.name="---a";
r.sex="boy";
}
else{
r.name="+++b";
r.sex="girl";
}
x=(x+1)%2;
//写完数据表明有数据未读,置未读标识符。
r.flag=true;
//notify()唤醒一个处于等待状态的线程。不能确切的唤醒特定的线程,
//具体唤醒哪个线程由jvm决定,并且不是按照优先级。
r.notify();
}
}
}
}
class Output implements Runnable{
Res r;
Output(Res r){
this.r=r;
}
public void run(){
while(true){
//上锁;
//由于操作同一资源,需和Iuput上的锁一致。
//这样一旦上锁,另外一个操做共享资源的函数就不能操作共享数据。
synchronized(r){
if(!r.flag){
//么有未读数据则等待,直到另一线程存储了新的数据并唤醒该线程
try{r.wait();}catch(Exception e){}
}
System.out.println(r.name+"......"+r.sex);
//数据读取完毕,重置数据读取状态标识符。
r.flag=false;
//数据读取完毕,唤醒处于等待状态的线程。
//notify()唤醒一个处于等待状态的线程。不能确切的唤醒特定的线程,
//具体唤醒哪个线程由jvm决定,并且不是按照优先级。
r.notify();
}
}
}
}
class waitNotifyDemo{
public static void main(String[] args){
Res r=new Res();
//使两个线程操作同一对象。
Output out=new Output(r);
Input in=new Input(r);
//构建两个线程,虽然是两个线程,但操作的是同一个对象中的共享资源。
Thread t1=new Thread(in);
Thread t2=new Thread(out);
//启动线程。
t1.start();
t2.start();
}
}
等待唤醒机制例程优化
//多线程间通信。
//功能:
// 1.Input类向资源中写入信息;
// 2.Output类从资源中读取信息;
//共享资源类;
class Res{
private String name;
private String sex;
//定义读写操作完成标识。flag为真:有未读的数据,flag为假:数据已读
private boolean flag=false;
//设置共享资源数据
//由于是对共享数据操作,需上锁。
public synchronized void set(String name,String sex){
if(this.flag){
try{this.wait();}catch(Exception e){}
}
this.name=name;
this.sex=sex;
flag=true;
//唤醒处于等待状态的线程,注意此处使用this。
this.notify();
}
//输出共享资源数据
//由于是对共享数据操作,需上锁。
public synchronized void out(){
//没有未读数据则等待。
if(!this.flag){
try{this.wait();}catch(Exception e){}
}
System.out.println(name+"......"+sex);
flag=false;
//唤醒处于等待状态的线程,注意此处使用this。
this.notify();
}
}
//实现Runnable接口的类;
class Input implements Runnable{
//定义共享资源的类参数,然后传递给构造函数;
//目的是操作同一个共享资源的对象;
Res r;
Input(Res r){
this.r=r;
}
//重写Runnable接口的run方法;
public void run(){
int x=0;
while(true){
if(x==0){
r.set("-----A","--boy");
}
else{
r.set("+++++B","++girl");
}
x=(x+1)%2;
}
}
}
class Output implements Runnable{
Res r;
Output(Res r){
this.r=r;
}
public void run(){
while(true){
r.out();
}
}
}
class OptimizeThread{
public static void main(String[] args){
Res r=new Res();
//使两个线程操作同一对象。
new Thread(new Output(r)).start();
new Thread(new Input(r)).start();
/*
Output out=new Output(r);
Input in=new Input(r);
//构建两个线程,虽然是两个线程,但操作的是同一个对象中的共享资源。
Thread t1=new Thread(in);
Thread t2=new Thread(out);
//启动线程。
t1.start();
t2.start();
*/
}
}
生产者消费者实例
class Resource{
private String name;
private int count=1;
private boolean flag;
public synchronized void set(String name){
//此处使用if语句只判断一次,当有多个线程进入if语句并处于等待状态时,
//容易爆发安全隐患。改为while。
//此处的notify唤醒的应该是out语句中的线程,但notify唤醒的线程较单一
//改为notifyAll。
while(flag){ //使进入该语句并处于等待状态的多个线程唤醒时都判断flag
try{
wait();
}
catch(Exception e){
}
}
this.name=name+"......"+count++;//此处将商品名称自动加上商品编号。
System.out.println("\t\t\t++++++product::"+this.name);
flag=true;
this.notify();
}
public synchronized void out(){
//此处使用if语句只判断一次,当有多个线程进入if语句并处于等待状态时,
//容易爆发安全隐患。改为while。
//此处的notify唤醒的应该是set语句中的线程,但notify唤醒的线程较单一
//改为notifyAll。
while(!flag){ //使进入该语句并处于等待状态的多个线程唤醒时都判断flag
try{
wait();
}
catch(Exception e){
}
}
System.out.println("------consumer::"+this.name);
flag=false;
this.notifyAll();
}
}
class consumer implements Runnable{
private Resource r;
public void run(){
while(true){
r.out();
}
}
consumer(Resource r){
this.r=r;
}
}
class product implements Runnable{
private Resource r;
public void run(){
while(true){
r.set("商品");
}
}
product(Resource r){
this.r=r;
}
}
class ProConDemo{
public static void main(String[] args){
Resource r=new Resource();
product pro=new product(r);
consumer con=new consumer(r);
Thread p1=new Thread(pro);
Thread c1=new Thread(con);
Thread p2=new Thread(pro);
Thread c2=new Thread(con);
Thread p3=new Thread(pro);
Thread c3=new Thread(con);
p1.start();
c1.start();
p2.start();
c2.start();
p3.start();
c3.start();
}
}
本方线程只唤醒对方线程
/*
** JDK1.5中提供了多线程的升级解决方案。
** 将同步synchronized替换成显式Lock操作。
** 将Object中的wait,notify,notifyAll替换为Condition对象。
** 该对象可以通过Lock锁对象的方法获取。
** 该对象可以调用awake(),signal(),signalAll().
** 该实例实现了:本方线程只唤醒对方线程的操作。
*/
import java.util.concurrent.locks.*;
class Resource{
private String name;
private int count=1;
private boolean flag;
//创建Lock对象。
final Lock lock=new ReentrantLock();
//通过Lock对象的方法创建Condition对象。
final Condition condition_con=lock.newCondition();
final Condition condition_pro=lock.newCondition();
public void set(String name)throws InterruptedException{ //awake方法提示有异常抛出
//直接上锁。
lock.lock();
try{
while(flag){
condition_pro.await(); //挂起本方线程。
}
this.name=name+"......"+count++;//此处将商品名称自动加上商品编号。
System.out.println("\t\t\t++++++product::"+this.name);
flag=true;
condition_con.signal(); //唤醒对方线程。
}
//无论程序如何运行,最后都要解锁。
finally{
lock.unlock();
}
}
public void out(){
//直接上锁。
lock.lock();
try{
while(!flag){ //使进入该语句并处于等待状态的多个线程唤醒时都判断flag
try{
condition_con.await(); //挂起本方线程。
}
catch(Exception e){
}
}
System.out.println("------consumer::"+this.name);
flag=false;
condition_pro.signal(); //唤醒对方线程。
}
//无论程序如何运行,最后都要解锁。
finally{
lock.unlock();
}
}
}
class consumer implements Runnable{
private Resource r;
public void run(){
try{ //捕捉定义的out方法中的异常。
while(true){
r.out();
}
}
catch(Exception e){
}
}
consumer(Resource r){
this.r=r;
}
}
class product implements Runnable{
private Resource r;
public void run(){
try{ //捕捉定义的set方法中的异常。
while(true){
r.set("商品");
}
}
catch(Exception e){
}
}
product(Resource r){
this.r=r;
}
}
class newLock{
public static void main(String[] args){
Resource r=new Resource();
product pro=new product(r);
consumer con=new consumer(r);
Thread p1=new Thread(pro);
Thread p2=new Thread(pro);
Thread p3=new Thread(pro);
Thread c1=new Thread(con);
Thread c2=new Thread(con);
Thread c3=new Thread(con);
p1.start();
p2.start();
p3.start();
c1.start();
c2.start();
c3.start();
}
}
中断线程
//线程的中断。
//线程的运行一般都是循环结构。只要构建中断循环标识就ok。
//对于上锁的线程,需要使用:对象.interrupt();来完成。
//interrupt激活冻结(等待)的线程。
class breakThread implements Runnable{
//构建循环中断标识。
public boolean flag=true;
public synchronized void run(){
while(flag){
try{
//线程一进入即进入冻结状态。
wait();
}
//捕获中断异常标识,然后置循环中断标识。
catch(InterruptedException e){
System.out.println("Breaking Thread....");
flag=false;
}
System.out.println(Thread.currentThread().getName()+".....run.");
}
System.out.println("Thread Over.");
}
public void changeFlage(){
flag=false;
}
}
class StopThread{
public static void main(String[] args){
int num=0;
breakThread bt=new breakThread();
Thread t=new Thread(bt);
t.start();
while(true){
if(++num==60){
System.out.println("need to stop thread!");
//num为60置线程中断,其实是激活冻结(等待)的线程。。
t.interrupt();
break;
}
System.out.println("Main Thread run......"+num);
}
}
}
守护线程
//守护线程;
//当运行的线程全部为守护线程时,java虚拟机退出。
//守护线程可理解为守护前台线程,但前台线程结束,后台线程(守护线程)也就么有存在的必要了。
//守护线程开启必须在守护线程启动之前。
class breakThread implements Runnable{
//构建循环中断标识。
public boolean flag=true;
public synchronized void run(){
System.out.println(Thread.currentThread().getName()+".....run.");
}
}
class StopThread{
public static void main(String[] args){
int num=0;
breakThread bt=new breakThread();
Thread t=new Thread(bt);
//守护线程开启必须在线程启动之前。
t.Daemon(true);
t.start();
while(true){
if(++num==60){
System.out.println("Stop main thread。");
//一旦main线程结束,只剩下t守护线程,java虚拟机退出。
break;
}
System.out.println("Main Thread run......"+num);
}
}
}
线程join方法
//join方法
//当A线程执行到了B线程的join方法时,A就会等待,等待B线程都执行完,A才会执行。
class Demo implements Runnable
{
public void run(){
for(int x=0;x<60;x++){
System.out.println(Thread.currentThread().getName()+"....."+x);
}
}
}
class joinDemo{
public static void main(String[] args)throws Exception{
Demo d=new Demo();
Thread t1=new Thread(d);
Thread t2=new Thread(d);
t1.start();
//加入join表明,t1线程申请获得cpu执行权,main线程暂时冻结。待t1线程执行完毕,main线程恢复。
t1.join();
t2.start();
//若在t1,t2线程启动后执行t1.join(),则main线程冻结,t1和t2线程交替执行,main线程只等待t1线程结束后即恢复运行。
for(int y=0;y<60;y++){
System.out.println(Thread.currentThread().getName()+"..."+y);
}
System.out.println("Main thread over.");
}
}