标签:任务 原来 nbsp 线程之间的通信 tar 之间 OLE 实例 定义
目录
线程基础内容
线程同步
线程间通信
程序Program 程序是一段静态的代码,它是应用程序执行的蓝本
进程Process 进程是指一种正在运行的程序,有自己的地址空间
进程的特点
线程Thread
线程特点
线程和进程的区别
线程的创建
线程的启动
两种线程创建方式的比较
继承Thread类方式的多线程
实现Runnable接口方式的多线程
实现Runnable接口方式要通用一些。
Thread类常用方法
3.线程的生命周期
新生状态:
就绪状态:
运行状态:
阻塞状态:
死亡状态:
Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。
线程调度器按照线程的优先级决定应调度哪个线程来执行。
线程的优先级用数字表示,范围从1到10
使用下述方法获得或设置线程对象的优先级。
注意:优先级低只是意味着获得调度的概率低。并不是绝对先调用优先级高后调用优先级低的线程。
Join ():
Sleep () :
yield ()
setDaemon()
stop()
当多个线程访问同一个数据时,容易出现线程安全问题。需要让线程同步,保证数据安全
线程同步:当两个或两个以上线程访问同一资源时,需要某种方式来确保资源在某一时刻只被一个线程使用
线程同步的实现方案
同步监视器
同步监视器的执行过程
线程同步的好处 : 解决了线程安全问题
线程同步的缺点
死锁
在生产者消费者问题中,仅有synchronized是不够的
Java提供了3个方法解决线程之间的通信问题
均是java.lang.Object类的方法 都只能在同步方法或者同步代码块中使用,否则会抛出异常
生产者消费者的实现思路
产品类
//产品类 public class Product { private String name;//馒头 玉米饼 private String color;//白色 黄色 private boolean isProduce = false;//是否生产产品 public synchronized void get(){ //如果没有生产,等待 if(isProduce == false) { wait(); } System.out.println(“消费者消费:”+name+“ ”+color); //消费产品 isProduce = false; //修改状态:没有生产 notify();//通知生产者生产 } public synchronized void put(String name,String color){ //如果已经生产,等待 if(isProduce == true){ wait();//生产产品 } this.name = name; this.color = color; System.out.println("生产者生产:"+this.name+" "+this.color); isProduce = true; //修改状态:已经生产 notify(); //通知消费者消费 } }
消费者线程
//消费者线程 public class Consumer implements Runnable{ private Product product; public Consumer() { super(); } public Consumer(Product product) { super(); this.product = product; } public void run() { while(true){ product.get(); } } }
生产者线程
//生产者线程 public class Producer implements Runnable { private Product product; public Producer() { } public Producer(Product product) { this.product = product; } public void run() { int i = 0; while (true) { if (i % 2 == 0) { product.put("馒头", "白色"); } else { product.put("玉米饼", "黄色"); } i++; } } }
测试类
//测试类 public class TestCommunication { public static void main(String[] args) { //创建产品类(生产者和消费者操作的是同一个产品) Product product = new Product(); //创建两个线程 Consumer c = new Consumer(product); Thread t1 = new Thread(c); Producer p = new Producer(product); Thread t2 = new Thread(p); //启动两个线程 t1.start(); t2.start(); } }
补充:
为什么通信?
不通信就无法实现生产和消费的交替进行
如何通信:wait 等待 notify唤醒 notifyAll 唤醒所有的阻塞线程
代码示例:
/** * 测试两种实现线程方式的区别 * 区别 * * @author Terry * */ public class ThreadDemo3 { /** * @param args */ public static void main(String[] args) { //new了两个线程对象——s1和s2 //其中两个对象各对应一个内存区域。线程运行过程中运行都是自己内存块中的数据 Shop1 s1 = new Shop1("小武"); s1.start(); Shop1 s2 = new Shop1("小潘"); s2.start(); /* //实例化了两个线程对象,所以分配了两块内存空间 //执行过程中操作的是自己的内存空间 Shop2 s3 = new Shop2("小武"); s3.run(); Shop2 s4 = new Shop2("小潘"); s4.run(); //实际实例化了两个线程对象 //所以同样分配两个内存空间 Thread t1 = new Thread(new Shop2("小武")); t1.start(); Thread t2 = new Thread(new Shop2("小潘")); t2.start(); //创建了两个线程对象,但是使用的是同一个对象——s5 Shop2 s5 = new Shop2("w"); Thread t3 = new Thread(s5); t3.start(); Thread t4 =new Thread(s5); t4.start(); */ } } /** * 因为业务的拓展,现在可以实现多窗口的出售 * 要求:每天只卖10个 * @author Terry * */ class Shop1 extends Thread{ //private int count = 10; //使用静态变量可以有效的实现资源共享(因为在内存中只有一份count) private static int count = 10; public Shop1(String name) { super(name); } public void run(){ //判断是否已经卖完 while(count>0){ count--; System.out.println(this.getName() +"卖出了一个烧饼" + ",现在剩余" + count); } } } /** * 使用接口实现上面的代码 * @author Terry * */ class Shop2 implements Runnable{ //私有变量,存储剩余烧饼的个数 private int count = 10; //存储当前人的姓名 private String name=""; public Shop2(String name) { this.name = name; } /** * 实现销售的方法 */ public void run(){ //判断是否已经卖完 while(count>0){ count--; System.out.println(Thread.currentThread().getId() + "、" + this.name +"卖出了一个烧饼" + ",现在剩余" + count); } } }
标签:任务 原来 nbsp 线程之间的通信 tar 之间 OLE 实例 定义
原文地址:https://www.cnblogs.com/Vincent-yuan/p/13124245.html