您的位置:首页 > 职场人生

黑马程序员-------线程(下)

2014-03-12 16:54 337 查看
----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

线程之间的通讯

package day12;
/**
* 线程之间的通讯
* @author hao
*
*多个线程操作同一个资源,但是操作的动作不同
*
*等待唤醒机制
*根据现实生活,我们不仅需要 各个线程访问数据实现同步,还要让各个线程之间有相互的制约
*
*例如:下面这个程序我们 需要的是存一个数据,取出一个数据
*其结果:
*	mick========boy
小红========女
mick========boy
小红========女
mick========boy
小红========女
mick========boy
小红========女
*
*
*wait(); notify();  notifyAll();
*它们对持有监视器的线程进行操作,所以要使用在同步当中
*
*这些方法为什么要定义在Object类当中
*在操纵同步中的线程时,只有同一个锁上的被等待的线程,才可以被同一个锁上的notify唤醒
*不可以对不同锁中的线程进行唤醒。等待唤醒必须是同一个锁
*锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类当中国
*
*/

//资源
class Res
{
private String name;
private String sex;
boolean flag = false;

public Res(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}

public Res() {
// TODO Auto-generated constructor stub
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

}
//输入资源
class Input implements Runnable
{
private Res r ;
public Input(Res r) {
super();
this.r = r;
}

public  void run()
{
boolean flag = false;
while(true)
{
synchronized(Res.class){
if(r.flag)
try
{
Res.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

if(flag){
r.setName("mick");
r.setSex("boy");

flag =false;
}else
{
r.setName("小红");
r.setSex("女");

flag = true;
}
r.flag = true;
Res.class.notify();
}
}
}
}
//输出资源
class Output implements Runnable
{
private Res r ;

public Output(Res r) {
super();
this.r = r;
}

public  void run()
{
while(true)
synchronized(Res.class)
{
if(!r.flag)
try {
Res.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(r.getName()+"========"+r.getSex());
r.flag = false;
Res.class.notify();
}
}
}
public class InputOutputDemo {
public static void main(String[] args) {
Res r = new Res();

Thread t1  = new Thread(new Input(r));
Thread t2  = new Thread(new Output(r));

t1.start();
t2.start();

}
}

生产者和消费者

package day12;
/**
* 线程通信  生产者消费者
* @author hao
*
*对于多个生产者和消费者
*为了让唤醒的线程再一次进行判断标记,我们要定义while判断标记
*
*为什么要定义notifyAll
*因为只用notify,容易出现只唤醒本方线程的情况,导致程序中的所有都等待
*
*程序运行结果一部分:
*	Thread-1..生产者..大米编号:26642
Thread-2..消费者..大米编号:26642
Thread-0..生产者..大米编号:26643
Thread-3..消费者..大米编号:26643
Thread-1..生产者..大米编号:26644
Thread-2..消费者..大米编号:26644
Thread-0..生产者..大米编号:26645
Thread-3..消费者..大米编号:26645
Thread-1..生产者..大米编号:26646
Thread-2..消费者..大米编号:26646
Thread-0..生产者..大米编号:26647
*/
class Resource
{
private String name;
private int id = 1;
boolean flag = false;
//存资源
public synchronized void set(String name){

while(flag)//if 不能再判断 flag  程序会继续向下执行
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
this.name = name + "编号:"+id++;
System.out.println(Thread.currentThread().getName()+"..生产者.."+this.name);
flag = true;
this.notifyAll();
}
//输出资源
public synchronized void out(){
while(!flag)
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"..消费者.."+this.name);
flag = false;
this.notifyAll();
}
}

class Producer implements Runnable
{
Resource r;
public Producer(Resource r) {
this.r = r;
}
public void run()
{
while(true)
r.set("大米");

}
}

class Consumer implements Runnable
{
Resource r;
public Consumer(Resource r) {
this.r = r;
}
public void run(){
while(true)
r.out();
}
}

public class ProducerConsumerDemo {
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();
}
}


JDK1.5多线程新特性

package day12;

/**
*  JDK1.5 线程新特性
* @author hao
*
*JDK1.5 提供了多线程升级解决方案
*将现实Lock操作替换成 同步synchronized
*将condition对象替换了Object中的wait,notify,notifyAll
*给对象可以用Lock锁,进行获取
*/
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Resource2
{
private String name;
private int id = 1;
boolean flag = false;
private Lock lock = new ReentrantLock();//创建锁
private Condition condition_pro = lock.newCondition();//关联锁
private Condition condition_con = lock.newCondition();
//存资源
public  void set(String name) throws InterruptedException{
lock.lock();
try {
while(flag)
//if 不能再判断 flag  程序会继续向下执行

condition_pro.await();

this.name = name + "编号:"+id++;
System.out.println(Thread.currentThread().getName()+"..生产者.."+this.name);
flag = true;
condition_con.signal();
}finally
{
lock.unlock();
}

}
//输出资源
public  void out() throws InterruptedException{
lock.lock();
try {
while(!flag)

condition_con.await();

System.out.println(Thread.currentThread().getName()+"..消费者.."+this.name);
flag = false;
condition_pro.signal();
}finally
{
lock.unlock();
}
}
}

class Producer2 implements Runnable
{
Resource2 r;
public Producer2(Resource2 r) {
this.r = r;
}
public void run()
{
while(true)
try {
r.set("大米");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

class Consumer2 implements Runnable
{
Resource2 r;
public Consumer2(Resource2 r) {
this.r = r;
}
public void run(){

while(true)
try {
r.out();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

public class ProducerConsumerDemo2 {
public static void main(String[] args) {
Resource2 r = new Resource2();

new Thread(new Producer2(r)).start();
new Thread(new Producer2(r)).start();
new Thread(new Consumer2(r)).start();
new Thread(new Consumer2(r)).start();
}
}

线程的停止

package day12;
/**
* 线程的停止
* @author hao
*
*老版本的stop方法已经过时,如何停止线程
*多线程的运行,一般采用循环结构。只要控制好循环,
*就可以让run方法结束,随之线程就结束啦
*
*特殊情况:
*当线程处于冻结状态
*就不会读取到标记。那么线程就不会结束
*
*当没有指定的方式让冻结的线程恢复到运行状态时,这是需要对冻结进行清除
*强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束。
*
*Thread类提供该方法interrupt();
*/
class StopThread implements Runnable
{
boolean flag = true;
public synchronized void run()
{
while(flag)
{
try {
wait();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()+"...Exception");
flag = false;
}
System.out.println(Thread.currentThread().getName()+"...run");

}
}
public void changeFlag()
{
flag = false;
}
}

public class StopThreadDemo {
public static void main(String[] args) {
StopThread st = new StopThread();
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){
//st.changeFlag();
t1.interrupt();
t2.interrupt(); //是冻结线程复活
break;
}
System.out.println(Thread.currentThread().getName()+num);
}
System.out.println("over");
}
}

Thread其他方法

package day12;
/**
* join 方法的应用  线程的优先级
* @author hao
*
*如果A线程在B线程之前  A线程采用的join方法  B线程需要等待A线程运行完才能运行
*
*join可以用来临时加入线程
*
*下面程序运行结果一部分:
*	Thread-0..57
Thread-0..58
Thread-0..59
main0
main1
main2
main3
main4
Thread-1..0
Thread-1..1
*
*public final void setPriority(int newPriority)
*更改线程的优先级。
*
*public static void yield()
*暂停当前正在执行的线程对象,并执行其他线程。
*/
class Demo implements Runnable
{
public void run()
{
for(int i = 0; i < 60; i++)
{
System.out.println(Thread.currentThread().getName()+".."+i);

}
}
}

public class JoinDemo {
public static void main(String[] args) throws InterruptedException {
Demo d  = new Demo();

Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
//t1.setPriority(Thread.MAX_PRIORITY);
t2.start();

//t1.join();
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
}
}

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息