栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA多线程创建、信息共享、管理、消费者与生产者案例、死锁案例等。

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA多线程创建、信息共享、管理、消费者与生产者案例、死锁案例等。

一、java多线程创建

1.Thread类

-java.lang.Thread 	
-线程继承Thread类,实现run方法
public class Thread1 extends Thread{
	public void run(){}
}

2.Runnable接口

-java.lang。Runnable接口
-线程实现Runnable接口,实现run方法
实现Runnable的对象必须包装在Thread类里面,才可以启动

public class Thread2 implements Runnable{
	public void run(){}
}

拓展:java的四个主要接口
(1)Clonable ,用于对象克隆;
(2)Comparable,用于对象比较;
(3)Serializable,用于对象序列化;
(4)Runnalbe,用于对象线程化;

线程启动

  • start方法,会自动以新进程调用run方法
  • 直接调用run方法,将会变成串行执行(即一个CPU去执行一个进程))
  • 同一个进程,多次start会报错,只执行第一次start方法(多线程对象都start后,哪一个先执行,完全由JVM操作系统来主导,程序员无法指定)
  • 多个线程启动,其启动的先后顺序是随机的
  • 线程无需关闭,只要其run方法执行结束后,自动关闭
  • main函数(线程)可能早于线程结束,整个程序并不终止
  • 整个程序终止是等所有的线程都终止(包括main函数线程)

Thread VS Runnable
–Thread类实现Runnable
–Thread占据了父类的名额(不能再去继承其它的类了),不如Runnable方便
–Runnable启动时需要Thread类的支持
–Runnable更容易实现多线程中的资源共享
–结论:建议实现Runnable接口来完成多线程


二、JAVA多线程信息共享
  • 通过static变量(一般是通过继承Thread类来实现)
  • 同一个Runnable类的成员变量(不需要设置静态变量static)
  • (volatile关键字):解决主存与工作缓存数值不相等的问题

关键步骤加锁限制

  • 互斥:某一个线程运行一个代码段(关键区),其它线程不能同时运行这个代码段。

  • 同步:多个线程的运行,必须按照某一种规定的先后顺序来运行。

  • 互斥是同步的一个特例;

互斥的关键字synchronized -synchronized代码块/函数,只能一个线程进入;
synchronized加大性能负担,但是使用简便 ;
抢到锁的线程运行代码块,没有抢到锁的线程则去等待;


JAVA多线程管理

1.线程状态

  • -NEW刚创建(new)
  • -RUNNABLE就绪态(start)
  • -RUNNING运行态(run)
  • -BLOCK阻塞(sleep)
  • -TERMINATED结束

2.线程的消亡

  • Thread的部分API已经废弃

  • 暂停和恢复suspend/resume

  • 消亡stop/destroy

  • 线程阻塞和唤醒

    a.   sleep,时间一到,自己会醒来
    b.   wait/notify/notifyAll,等待,需要别人来唤醒
    c.   join,等待另一个线程结束
    d.   -interrupt,向另一个线程发送中断信号,该线程收到信号会触InterruptedException(可  解除阻塞),并进行下一步处理。
    

3.线程的暂停和终止

  • •线程被动的暂停和终止

     ○ 依靠别的线程来拯救自己
     ○ 没有及时释放资源
    
  • •线程主动暂停和终止

     ○ 定期检测共享变量
     ○ 如果需要暂停或者终止,先释放资源,再主动动作
     ○ 暂停:Thread.sleep(),休眠
     ○ 终止:run方法结束,线程终止
    

4.死锁

  • •多线程死锁

     ○ 每个线程互相持有别人需要的锁(哲学家吃面问题)
     ○ 预防死锁,对资源进行等级排序
    
  • 守护(后台)线程

     ○ 普通线程的结束,是run方法结束
     ○ 守护线程结束,是run方法运行结束,或main函数结束
     ○ 守护线程永久不要访问资源,如文件或数据库等
    
t.setDaemon(ture)//t是一个线程

三、java线程案例(生产者和消费者案例、死锁案例): 案例一:生产者与消费者


Test.java代码如下

public class Test {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Storage storage=new Storage();
		//创建两个生产者
		Producer p1=new Producer(storage);
		Producer p2=new Producer(storage);
		//创建消费者两个
		Consumer c1=new Consumer(storage);
		Consumer c2=new Consumer(storage);
		
		Thread t3=new Thread(p1);
		Thread t4=new Thread(p2);
		t3.setName("生产者t3");
		t4.setName("生产者t4");
		
		Thread t1=new Thread(c1);
		Thread t2=new Thread(c2);
		t1.setName("消费者t1");
		t1.setName("消费者t2");
	
		t3.start();
		t4.start();
		try {
			Thread.sleep(400);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		t1.start();
		t2.start();
	}
}

Storage.java代码如下:(仓库)

public class Storage {
	private Product[] products=new Product[10];
	private int  top=0;
	//生产一个产品
	public synchronized void push(Product p) throws InterruptedException {
		//当仓库满的时候
		while(top==products.length) {
			System.out.println("仓库已满 wait");
			wait();
		}
		//仓库不满的时候
		products[top]=p;
		top++;
		System.out.println(Thread.currentThread().getName()+"生产一个商品"+p);
		notifyAll();
	}
	//消耗一个产品
	public synchronized Product pop() throws InterruptedException {
		//当仓库没有商品时
		while(top==0) {
			System.out.println("仓库为空 wait");
			wait();
		}
		//当仓库有商品时
		top--;
		Product p=new Product(products[top].getId(),products[top].getName());
		products[top]=null;
		System.out.println(Thread.currentThread().getName()+"消费一个商品"+p);
		notifyAll();
		return p;
	}
}

Product.java代码如下:(产品)

public class Product {
	private int id;
	private String name;
	Product(int id ,String name){
		this.id=id;
		this.name=name;
	}
	public String toString() {
		return "id:"+id+"name:"+name;
	}
	public int getId() {
		return id;
	}
	public String getName() {
		return name;
	}
}

Consumer.java代码如下:(消费者)

public class Consumer implements Runnable {
	private Storage storage;
	public Consumer(Storage storage) {
		// TODO Auto-generated constructor stub
		this.storage=storage;
	}
	public void run() {
		int i=0;
		while(i<10) {
			i++;
			try {
				storage.pop();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			};
		}
	}
}

Producer.java代码如下:(生产者)

public class Producer implements Runnable {
	private Storage storage;
	public Producer(Storage storage) {
		// TODO Auto-generated constructor stub
		this.storage=storage;
	}
	public void run() {
		int i=0;
		Random m=new Random();
		while(i<10) {
			i++;
			Product p=new Product(i,"name"+m.nextInt(100));
			try {
				storage.push(p);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

运行截图:

案例二:死锁案例
public class ThredDemo5 {
	        public static Integer r1=1;
	        public static Integer r2=2;
	
	        public static void main(String[] args) throws InterruptedException {
	                // TODO Auto-generated method stub
	                Thread1 t1=new Thread1();	
	                Thread2 t2=new Thread2();
	                t1.start();
	             t2.start();
	        }
	}
	class Thread1 extends Thread{
	        public void run() {
	                synchronized (ThredDemo5.r2) {
	                        System.out.println("Thread1--llp1 is running !");  
	                }
	                        try {
	                                TimeUnit.SECONDS.sleep(3);
	                        } catch (InterruptedException e) {
	                                // TODO Auto-generated catch block
	                                e.printStackTrace();
	                        }
	                synchronized (ThredDemo5.r1) {
	                        System.out.println("Thread2--llp2 is running !");
	                }	
	        }	
	}
	class Thread2 extends Thread{
	        public void run() {
	                synchronized (ThredDemo5.r1) {
	                        System.out.println("Thread2--llp1 is running !");	
	                }
	                try {
	                        TimeUnit.SECONDS.sleep(3);
	                } catch (InterruptedException e) {
	                        // TODO Auto-generated catch block
	                        e.printStackTrace();
	                }
	                synchronized (ThredDemo5.r2) {
	                        System.out.println("Thread2--llp2 is running !");
	                        
	                }
	        }
	}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/855426.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号