您的位置:首页 > 编程语言 > Java开发

java多线程的同步 通信以及生产消费者问题

2012-03-18 15:59 239 查看
Demo1

/* Runable接口比直接从Thread继承方便的多 。

* new Thread(...) ;这样即使我们传递了同一个实现了Runnable接口的多个对象那么 也是多个线程 ,而且多个线程共享数据域.

* 否则new Thread 创建的多个线程之间 互不相干 ,数据之间互不干涉

* 同步就是为了实现 在多个线程同时对一个资源进行操作的时候 要一个一个的执行 ,

* 只有等占有CPU的 线程完事之后 其他等待线程才能进入就绪状态等待运行

* java中可以用 synchrozined(Object obj){} 实现代码块的同步 参数是任意对象

* 不但可以利用synchronized语句块 也可以在方法的前面 声明 synchronized

* 同步原理是对象的标志位 初始为1 当进入代码块后 obj的标志位变为 0 这时候其他线程则不能 进入代码块执行 而进入等待状态

* 直到先进入的那个线程完事然后就会为这个线程解锁 。 其他线程才可能开始运行 火车票的售票系统就是一个多线程很好的运用的例子

* 同步是以程序的性能为代价的 ,同步方法是以类的this对象为同步对象的 而 synchronized块是以我们指定的对象为 同步对象

* 如果想让代码块和同步方法同步那么 使用的同步对象 必须都为this

*/

public class ThreadDemo2

{

public static void main(String []args)

{

MyThread mt=new MyThread() ;

//mt.start() ;

new Thread(mt) .start() ;

try

{

Thread.sleep(10) ; //每当产生一个线程CPU不会立马去执行 ,这之间既有一个微小的时间间隔 。

}

catch(Exception e)

{

System.out.println(e.toString()) ;

}

mt.str="method";

new Thread(mt) .start() ;

}

}

class MyThread implements Runnable// extends Thread

{

int tickets=100 ;

String str=new String("");

public void run()

{

if(str.equals("method"))

{

while(true)

{

running() ;

}

}

else

{

while(true)

{

synchronized(str)

{

if(tickets>0 )

{

System.out.println("block:"+Thread.currentThread().getName()+"sells"+tickets--);

}

}



}

}

}

public synchronized void running()

{

if(tickets>0)

{

try{Thread.sleep(10);}catch(Exception ex){}

System.out.print("method:") ;

System.out.println(Thread.currentThread() +"sell " + tickets-- ) ;

}

}

}



Demo2:

/*

* java多线程中 有前台线程和后台线程,前台线程 是指 main所在的主线程 和其他 创建的线程 ,如果在线程调用start 之前调用 setDeamon(true)

* 那么 这个线程就是一个后台线程,在进程中如果没有一个前台线程 那么后台线程也随之退出,从而进程也退出 。如果没有调用setDeamon(true)或者

* 调用setDeamom(false)那么这个线程就是前台线程 ,只要一个进程中还存在前台线程 那么即使mian方法所在的线程退出了 ,那么这个前台子线程也会继续执行

* 直至退出 。

* Tread类额join方法 是将一个线程合并到另一个线程中, 可以设置合并的时间间隔

* 我们实现自己的线程类有2中方法 :

* 1、直接从Thread继承而来 实现 run方法 。

* 2、实现Runnable接口,并且实现run方法 。 Thread th=new Thread(....) ;//吧我们自己实现的类的对象作为参数传进去 .

* join 方法可以将一个线程合并到另一个线程 中 而且还可以指定线程合并的时间间隔

*

*/

public class ThreadDemo1

{

public static void main(String[]args)

{

//MyThread tt=new MyThread() ; tt.start() ;可以从 Thread类派生一个线程类

Thread tt=new Thread(new MyThread()) ; //可以通过Thread类的带参数的构造方法 传递一个实现了Runnable接口的对象

// tt.setDaemon(true) ;//将线程设置为 后台线程 主线层退出这个线程也会随着退出

tt.start() ;

int index=0 ;

while(true)

{

if(index++==100)

try{

tt.join(5000) ;

}

catch(Exception ex)

{

System.out.println(ex.toString()) ;

}



System.out.println("run:"+Thread.currentThread().getName()) ;

}

}

}

class MyThread implements Runnable//extends Thread

{

public void run()

{

while(true)

{

System.out.println("run:"+Thread.currentThread().getName()) ;

}

}

}

Demo3:

/* 线程之间的通信是协调线程同步的重要方法 、

* Object类的 wait方法通告同步对象进入等待状态,直到其他线程得到同步对象 并且调用 notity方法 ,等待线程才会继续执行

* notify方法 是通告同步对象的等待线程进入恢复运行

* notifyAll通告所有堵塞线程恢复运行

* 下面是一个生产消费者的问题 ,在对于类的操作的时候 一定要有面向对象的思想 。 否则 就会非常的杂乱

*/

class Producer implements Runnable

{

Q q ;

public Producer(Q q)

{

this.q=q ;

}

public void run()

{

int i=0 ;

while(true)

{

/* synchronized(q)

{

if(q.bFull==true)

try{q.wait() ;}catch(Exception ex){}

if(i==0)

{

q.name="zhangsan" ;

try{

Thread.sleep(1) ;

}catch(Exception ex){}

q.sex="male" ;

}

else

{

q.name="lisi" ;

q.sex="female" ;

}

q.bFull=true ;

q.notify() ;

}

i=(i+1)%2 ;

*/



if(i==0 )

q.push("zhangsan","male");

else

q.push("lisi","female") ;

i=(i+1)%2 ;

}



}

}

class Consumer implements Runnable

{

Q q ;

public Consumer(Q q)

{

this.q=q ;

}

public void run()

{

while(true)

{

/* synchronized(q)

{

if(!q.bFull)

{

try{q.wait() ;}catch(Exception ex){}

}

System.out.println(q.name+":"+q.sex) ;

q.bFull=false ;

q.notify() ;

}

*/

q.get() ;

}

}

}

class Q //以面向对象的思想对线程之间的通信进行封装从而实现消费者 生产社的问题

{

String name="unknown" ;

String sex ="unknown" ;

boolean bFull=false ;

public synchronized void push(String name,String sex)

{

if(this.bFull==true)

try{wait() ;}catch(Exception ex){}

this.name=name ;

this.sex=sex ;

bFull=true ;

try{notify() ;}catch(Exception ex){}

}

public synchronized void get()

{

if(this.bFull==false)

try{wait() ;}catch(Exception ex){}

System.out.println("name:"+this.name+" sex:"+this.sex) ;

bFull=false ;

try{notify() ;}catch(Exception ex){}

}

}

class ThreadTest implements Runnable //这个线程类 来模拟线程的声明结束 因为Thread类的 stop suspend等方法都已经过时了

{ //所以有时候我们对于线程的开始和结束要自己设置标志位来

boolean bRun=true ;

int index=0 ;

public void stopMe()

{

bRun=false ;

}

public void run()

{

while(bRun)

{

if(++index>100)

stopMe() ;

System.out.println(Thread.currentThread().getName()+" is running!");

}



}



}

public class ThreadDemo3

{



public static void main(String[]args)

{



Q q=new Q() ;

new Thread(new Producer(q)).start() ;

new Thread(new Consumer(q)).start() ;



}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: