day14 多线程2

模拟线程通信之生产者和消费者

package _01_Product_Consumer;

public class app {
	public static void main(String[] args) {
		ShareResource share = new ShareResource();
		new Thread(new Product(share)).start();
		new Thread(new Consumer(share)).start();
	}

}

package _01_Product_Consumer;

public class Consumer implements Runnable {
	private ShareResource share = null;
	public Consumer(ShareResource share){
		this.share = share;
	}
	@Override
	public void run() {
		for(int i=0;i<1000;i++){
			share.popup();
		}
	}
	
}

package _01_Product_Consumer;

public class Product implements Runnable{
	private ShareResource share = null;
	public Product(ShareResource share){
		this.share = share;
	}

	@Override
	public void run() {
		for(int i=0;i<1000;i++){
			if(i % 2 != 0){
				share.push("著姐","女");
			}else{
				share.push("春哥"	,"男");
			}
		}
	}
	
}

package _01_Product_Consumer;

public class ShareResource {
	private String name;
	private String sex;
	
	public void push(String name,String sex){
		this.name = name;
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.sex = sex;
	}

	public void popup() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(name+"----"+sex);
	}
	
	
}

上述代码只是简单的模拟了下,如果通过Thread.sleep(100)方法,就会放大线程不安全的问题,男女性别不符合问题.

可以使用synchronized来修饰方法 达到同步,但是问题还是存在------生产者生产一个,消费者消费一个,应该是这样的情况 

解决这种情况的话使用wait和notify

package _03_wait;

public class ShareResouce {
	private String name;
	private String sex;
	
	private boolean flag = true;
	synchronized public void push(String name,String sex) {
		while(!flag){
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.name = name ;
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.sex = sex;
		flag = false;
		this.notify();
	}

	synchronized public void pop() {
		while(flag){
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(name+"-----"+sex);
		flag = true ;
		this.notify();
	}

}
还有中方法是使用lock机制

package _04_Lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ShareResouce {
	private String name;
	private String sex;
	private Lock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();
	private boolean isEmpty = true;
	synchronized public void push(String name,String sex) {
		lock.lock();
		try{
			while(!isEmpty){
				condition.await();
			}
			this.name = name;
			Thread.sleep(10);
			this.sex = sex;
			isEmpty = false;
			condition.signal();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
		
	
	}

	synchronized public void pop() {
		lock.lock();
		try{
			while(isEmpty){
				condition.await();
			}
			Thread.sleep(100);
			System.out.println(name+"-----"+sex);
			isEmpty = true;
			condition.signal();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			lock.lock();
		}
		
	}

}
死锁的问题,就是拿着线程不放,打个不巧当的比方就是,女方说:你先买房我再嫁给你.男方说:你先嫁给我,我再买房.

线程的生命周期

1 NEW 只是new而已

2 RUNNABLE 运行了start方法

3 BLOCKED 在IO中,如果main中存在System.in.read()//接受键盘输入

如果不输入那么main线程一个会在阻塞中

4 WAITING 线程中使用wait方法

5 TIMED_WAITING 就是在使用Thread.sleep()

6 TERMINATED 线程结束.

控制线程
联合线程  A线程需要拿到B线程的执行结果才能继续运行.

package _05_kongzhi_Thread;

class JoinThread extends Thread{
	@Override
	public void run() {
		for(int i=0;i<100;i++){
			System.out.println("联合"+i);
		}
	}
}
public class Lianhe {
	public static void main(String[] args) throws Exception {
		System.out.println("程序开始");
		JoinThread jh = new JoinThread();
		for(int i=0;i<50;i++){
			System.out.println("main"+i);
			if(i == 5){
				jh.start();//这里还是cpu调度问题,不会立马执行jh线程的
			}
			if(i==10){
				jh.join();//这里的话为什么会成功,相当于强制挤进来的,我要运行
			}
		}
		System.out.println("程序结束");
	}

}

后台线程  JVM的垃圾回收器就是典型的后台线程

package _05_kongzhi_Thread;
class Daemonxx extends Thread{
	@Override
	public void run() {
		for(int i=0;i<1000;i++){
			System.out.println("是否是后台线程"+this.isDaemon());
		}
	}
}
public class DaemonDemo {
	public static void main(String[] args) {
		System.out.println("main线程是否是主线程"+Thread.currentThread().isDaemon());
		Daemonxx xx = new Daemonxx();
		xx.setDaemon(true);
		xx.start();
		for(int i=0;i<10;i++){
			System.out.println("main...");
		}
	}

}

上图是守护线程的执行结果,可以看出主方法结束了还要再执行后台进程,确认是否真的结束了.

线程睡眠 就是sleep()

线程优先级   有几个常量  MAX_PRIORITY10 MIN_PRIORITY1  NORM_PRIORITY5 

线程的优先级主要作用是可以获得执行机会次数多少有关,并非线程级别越高就优先执行,哪个线程先运行还是取决于CPU的调度

package _05_kongzhi_Thread;
class priority extends Thread{
	priority(String name){
		super(name);
	}
	@Override
	public void run() {
		for(int i=0;i<100;i++){
			System.out.println(this.getName()+"---"+ i );
		}
	}
}
public class PriorityDemo {
	public static void main(String[] args) {
		priority p1 = new priority("优先级高的");
		priority p2 = new priority("优先级低的");
		p1.setPriority(10);
		p1.start();
		p2.start();
		
	}

}


线程礼让

void yield()  没啥用,你想让,但是谁先执行还是取决于CPU的

Thread过时的方法和定时器

void resume();//取消挂起

suspend();//挂起线程

void stop();//终止线程

已经被wait和notify取代,知道就好.

Timer

package _06_Timer;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class Test {
	public static void main(String[] args) {
		/*
		Date d = new Date(System.currentTimeMillis() + 3000);
		new Timer().schedule(new TimerTask(){
			@Override
			public void run() {
			System.out.println("hello");
			}
		}, d);
		*/
		new Timer().schedule(new TimerTask(){
			@Override
			public void run() {
				System.out.println(new Date().toLocaleString());
			}
		}, 0, 1000);
		
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值