—————————— ASP.Net+Android+IOS开发、.Net培训、期待与您交流!——————————
多线程之间的通信
其实就是多线程在操作同一资源,但是操作的动作不同
wait();
notify();
notifyAll();
都使用在同步中,因为要对持有监视器的线程操作,所以都要使用在
同步中,因为只有同步才具有监视器
为什么这些操作线程方法要定义在Object类中呢?
因为这些方法在操作同步中的线程,都必须要在标识他们的操作线程只有
的锁,只有同一个锁上的被等待线程,可以被同一个锁notify()唤醒,不可以
对不同锁中的线程进行唤醒,也就是说等待和唤醒是同一个锁.
而锁可以使任意对象,所以可以被任意对象调用的方法定义在Object中
对于多个生产者和消费者
为什么要定义while判断标记?
原因:让被唤醒的线程再一次判断标记
为什么定义notifyAll?
因为需要唤醒的对方线程.因为只用notify,容易出现只唤醒本方线程的
情况,导致程序中的所有程序都在等待.
如何只唤醒对方呢?
需要导包:java.util.concurrent.locks;
JDK1.5中提供了多线程升级解决方法.将同步synchronized替换成显示的Lock
操作. 将Object中的wait,notify,notifyAll替换成Condition对象,该对象
可以通过Lock锁进行获取?
Lock lock=new ReentrantLock();
Condition con=lock.newCondition();
在该示例中实现本方只唤醒对方操作?
停止线程
stop方法已经过时?
如何停止线程?只有一种方法就是run方法结束
开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以
让run方法结束.也就是线程结束
特殊情况,当线程处于冻结状态,就不会读到标记,那么线程就不会结束
当没有指定的方式让冻结的线程恢复到运行状态,这时需要对冻结进行清除
,强制性制止过程恢复到运行状态中来,这样就可以操作标记让线程结束
Thread类提供了该方法 interrupt();
守护线程:
setDaemon();
将该线程标志为守护线程,或用户线程就是后台线程
必须在启动线程前调用,主线程运行完毕,守护线程机会结束.jvm虚拟机结束
join();
当A线程执行到了B线程的join方法时,就会等待,等b线程执行完毕.
A才会执行
join可以用来临时加入线程执行
toString();
返回线程名称,线程优先级,线程组
ThreadGroup 线程组几乎用不上,就是谁调用该线程,它就属于哪个组,开发不常见
setPriority();//默认优先级是5
MAX_PRIORITY; //最高优先级10
MIN_PRIORITY; //最低优先级1
NORM_PRIORITY;//默认优先级5
yield(); //暂停当前运行线程
当某些代码需要被同时执行时,就等着成线程对象.
多线程之间的通信
其实就是多线程在操作同一资源,但是操作的动作不同
/*
多线程之间的通信
一个线程负责写,一个线程负责读
*/
class Demo
{
public static void main(String[] args)
{
Resource r=new Resource();
new Thread(new WriterThread(r)).start();
new Thread(new ReaderThread(r)).start();
}
}
/*操作共同的资源*/
class Resource
{
private String name;
private String sex;
private boolean flag=true;
public void setFlag(boolean flag){
this.flag=flag;
}
public synchronized void setInfo(String name,String sex){
while(flag){ //每次都判断标记
try
{
wait();
}
catch (InterruptedException e)
{
}
}
this.name=name;
this.sex=sex;
flag=true;
notifyAll();
}
public synchronized void getInfo(){
while(!flag){
try
{
wait();
}
catch (InterruptedException e)
{
}
}
System.out.println(name+"-----"+sex);
flag=false;
notifyAll();
}
}
/*写入线程*/
class WriterThread implements Runnable
{
private Resource r;
public WriterThread(Resource r){
this.r=r;
}
public void run(){
int i=0;
while(true){
if(i%2==0){
r.setInfo("track","man");
}else{
r.setInfo("赖海娟","女");
}
i++;
}
}
}
/*读取线程*/
class ReaderThread implements Runnable
{
private Resource r;
public ReaderThread(Resource r){
this.r=r;
}
public void run(){
while(true){
r.getInfo();
}
}
}
wait();
notify();
notifyAll();
都使用在同步中,因为要对持有监视器的线程操作,所以都要使用在
同步中,因为只有同步才具有监视器
为什么这些操作线程方法要定义在Object类中呢?
因为这些方法在操作同步中的线程,都必须要在标识他们的操作线程只有
的锁,只有同一个锁上的被等待线程,可以被同一个锁notify()唤醒,不可以
对不同锁中的线程进行唤醒,也就是说等待和唤醒是同一个锁.
而锁可以使任意对象,所以可以被任意对象调用的方法定义在Object中
一对一生产者,消费者:
/*
生产者,消费者
*/
class Demo1
{
public static void main(String[] args)
{
Resource r=new Resource();
new Thread(new Producer(r)).start();
new Thread(new Consumer(r)).start();
}
}
/*共同所操作的资源*/
class Resource
{
private String ware;
private int count=1;
private boolean b=false;
public String getWare(){
return ware;
}
public synchronized void proWare(String ware){
while(b)
try
{
wait();
}
catch (InterruptedException e)
{
}
this.ware=ware+":::"+count++;
b=true;
notifyAll();
}
public synchronized void conWare(){
while(!b)
try
{
wait();
}
catch (InterruptedException e)
{
}
System.out.println("消费--------------"+ware);
b=false;
notifyAll();
}
}
/*生产者*/
class Producer implements Runnable
{
private Resource r;
public Producer(Resource r){
this.r=r;
}
public void run(){
while(true){
r.proWare("商品");
System.out.println("生产-----------"+r.getWare());
}
}
}
/*消费者*/
class Consumer implements Runnable
{
private Resource r;
public Consumer(Resource r){
this.r=r;
}
public void run(){
while(true)
r.conWare();
}
}
对于多个生产者和消费者
为什么要定义while判断标记?
原因:让被唤醒的线程再一次判断标记
/*
生产者 消费者
使用JDK1.5提供的解决方案
只唤醒对方的等待线程
*/
import java.util.concurrent.locks.*;
class Demo2
{
public static void main(String[] args)
{
Resource r=new Resource();
/*两个生产者*/
new Thread(new Producer(r)).start();
new Thread(new Producer(r)).start();
/*两个消费者*/
new Thread(new Consumer(r)).start();
new Thread(new Consumer(r)).start();
}
}
/*共同所操作的资源*/
class Resource
{
private String ware;
private int count=1;
private boolean b=false;
private Lock lock=new ReentrantLock();
private Condition con_pro=lock.newCondition();
private Condition con_con=lock.newCondition();
public String getWare(){
return ware;
}
public void proWare(String ware)throws InterruptedException{
lock.lock(); // 获取锁
while(b)
try
{
con_pro.await(); //等待
}
finally
{
lock.unlock();//释放锁
}
this.ware=ware+":::"+count++;
b=true;
con_con.signalAll();//唤醒对方的等待线程
}
public void conWare()throws InterruptedException{
lock.lock();
while(!b)
try
{
con_con.await();
}
finally
{
lock.unlock();
}
System.out.println(Thread.currentThread().getName()+"消费--------------"+ware);
b=false;
con_pro.signalAll();
}
}
/*生产者*/
class Producer implements Runnable
{
private Resource r;
public Producer(Resource r){
this.r=r;
}
public void run(){
while(true){
try
{
r.proWare("商品");
System.out.println(Thread.currentThread().getName()+"生产-----------"+r.getWare());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
/*消费者*/
class Consumer implements Runnable
{
private Resource r;
public Consumer(Resource r){
this.r=r;
}
public void run(){
while(true){
try{
r.conWare();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
为什么定义notifyAll?
因为需要唤醒的对方线程.因为只用notify,容易出现只唤醒本方线程的
情况,导致程序中的所有程序都在等待.
如何只唤醒对方呢?
需要导包:java.util.concurrent.locks;
JDK1.5中提供了多线程升级解决方法.将同步synchronized替换成显示的Lock
操作. 将Object中的wait,notify,notifyAll替换成Condition对象,该对象
可以通过Lock锁进行获取?
Lock lock=new ReentrantLock();
Condition con=lock.newCondition();
在该示例中实现本方只唤醒对方操作?
停止线程
stop方法已经过时?
如何停止线程?只有一种方法就是run方法结束
/*
如何停止线程 清除线程的冻结状态interrupt
*/
class Demo3
{
public static void main(String[] args)
{
Test t=new Test();
Thread tt=new Thread(t);
tt.start();
try
{
Thread.sleep(5000);
tt.interrupt(); //5秒清除线程的冻结状态,重新开始执行
}
catch (Exception e)
{
}
}
}
class Test implements Runnable
{
public synchronized void run(){
for (int i=0;i<100 ;i++ )
{
System.out.println(Thread.currentThread().getName()+"::"+i);
//假如出现wait,则线程冻结 需要清除该状态才可以继续执行
if(i==10)
try
{
wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以
让run方法结束.也就是线程结束
特殊情况,当线程处于冻结状态,就不会读到标记,那么线程就不会结束
当没有指定的方式让冻结的线程恢复到运行状态,这时需要对冻结进行清除
,强制性制止过程恢复到运行状态中来,这样就可以操作标记让线程结束
Thread类提供了该方法 interrupt();
守护线程:
setDaemon();
将该线程标志为守护线程,或用户线程就是后台线程
必须在启动线程前调用,主线程运行完毕,守护线程机会结束.jvm虚拟机结束
join();
当A线程执行到了B线程的join方法时,就会等待,等b线程执行完毕.
A才会执行
join可以用来临时加入线程执行
toString();
返回线程名称,线程优先级,线程组
ThreadGroup 线程组几乎用不上,就是谁调用该线程,它就属于哪个组,开发不常见
setPriority();//默认优先级是5
MAX_PRIORITY; //最高优先级10
MIN_PRIORITY; //最低优先级1
NORM_PRIORITY;//默认优先级5
yield(); //暂停当前运行线程
当某些代码需要被同时执行时,就等着成线程对象.
开发通常使用Thread的匿名子类或者Runnable的匿名子类
/*
setDaemon守护线程
join临时加入线程
toString//返回线程名称,优先级,线程组
setPriority//设置优先级
yield//暂停线程运行
*/
class Demo4
{
public static void main(String[] args)
{
Thread t1=new Thread(){
public void run(){
for (int i=1;i<=20 ;i++ )
{
System.out.println(Thread.currentThread().toString()+":::"+i);
/*
//当设置为守护线程时,即使wait 主线程运行完 主线程就会结束
if(i==10){
try
{
wait();
}
catch (InterruptedException e)
{
}
}
*/
}
}
};
Runnable r=new Runnable(){
public void run(){
for (int i=1;i<=20 ;i++ )
{
System.out.println(Thread.currentThread().toString()+":::"+i);
/*
//当设置为守护线程时,即使wait 主线程运行完 主线程就会结束
if(i==10){
try
{
wait();
}
catch (InterruptedException e)
{
}
}
*/
}
}
};
Thread t2=new Thread(r);
//t1.setPriority(Thread.MAX_PRIORITY);//设置t1的优先级为10 最大
//t1.setDaemon(true); //设置为守护线程
//t2.setDaemon(true);
t1.start();
t2.start();
t1.yield(); //暂停对当前运行线程 本人经测试 看不出啥 是不是单核电脑的忧桑?
//主线程
for (int i=1;i<=50 ;i++ )
{
System.out.println(Thread.currentThread().toString()+":::"+i);
}
/*
//join();//用来临时加入线程
try
{
t1.join();// 本人经测试 看不出啥 是不是单核电脑的忧桑?
}
catch (Exception e)
{
}
*/
}
}
—————————— ASP.Net+Android+IOS开发、.Net培训、期待与您交流!——————————