zoukankan      html  css  js  c++  java
  • java 多线程简单例子

    实现线程的方式是一,继承Thread类,重写父类的run()方法

    二,实现接口Runnable中的run()方法。

    下面是简单的例子

    例子1:银行存取钱问题

    package com.direct.demo;
    
    public class Bank {
    	private static int money;
    	public int getMoney(){
    		return money;
    	}
    	public void saveMoney(int m){
    		synchronized (this) {
    			System.out.println("存钱后的总金额:"+(money+=m));			
    		}
    	}
    	public void drawMoney(int m){
    		synchronized (this) {
    			Bank bank = new Bank();
    			if (bank.getMoney()<=0) {
    				System.out.println("没得钱,取个pi");
    			}else {
    				System.out.println("取钱后剩的总金额:"+(money-=m));			
    			}
    		}
    	}
    	
    	public static void main(String[] args) {
    		Man m1 = new Man();
    		Women w = new Women();
    		Thread t1 = new Thread(m1);
    		Thread t2 = new Thread(m1);
    		Thread t3 = new Thread(m1);
    		Thread t4 = new Thread(w);
    		Thread t5 = new Thread(w);
    		Thread t6 = new Thread(w);
    		t1.start();
    		t2.start();
    		t3.start();
    		t4.start();
    		t5.start();
    		t6.start();
    		}
    
    }
    
    class Man implements Runnable{
    	private Bank bank = new Bank();
    
    	public void run() {
    		int m = 100;
    		int i=0;
    		while (i<5) {
    				bank.saveMoney(m);
    				i++;
    				try {
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}	
    		}
    	}
    }
    class Women implements Runnable{
    	private Bank bank = new Bank();
    
    	public void run() {
    		int m = 100;
    		int i=0;
    		//bank.getMoney()>0
    		while (i<5) {
    					bank.drawMoney(m);
    				try {
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    		i++;
    		}
    	}
    	
    }
    

      例子2:生产者与消费者问题

    package com.direct.demo;
    
    public class Clerk {
    	private int product = -1;
    	
    	//这个方法由生产者调用
    	public synchronized void setProduct(int product){
    		if (this.product != -1) {
    			try {
    				wait();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		this.product = product;
    		System.out.printf("生产者设定 (%d)%n",this.product);
    		notify();
    	}
    	
    	//这个方法由消费者调用
    	public synchronized int getProduct(){
    		if (this.product==-1) {
    			try {
    				wait();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		int p = this.product;
    		System.out.printf("消费者取走 (%d)%n",this.product);
    		this.product = -1;
    		notify();
    		return p;
    	}
    
    	public static void main(String[] args) {
    		Clerk clerk = new Clerk();
    		new Thread(new ProducerInt(clerk)).start();
    		new Thread(new ConsumerInt(clerk)).start();
    	}
    	
    }
    
    class  ProducerInt implements Runnable{
    	private Clerk clerk;
    	public ProducerInt(Clerk clerk){
    		this.clerk = clerk;
    	}
    	public void run() {
    		System.out.println("生产者开始生产整数了..................");
    		for (int product = 1; product <= 10; product++) {
    			try {
    				Thread.sleep((int)Math.random()*300);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			clerk.setProduct(product);
    		}
    	}
    	
    }
    
    class ConsumerInt implements Runnable{
    	private Clerk clerk;
    	public ConsumerInt(Clerk clerk){
    		this.clerk = clerk;
    	}
    	public void run() {
    		System.out.println("消费者开始消耗整数........");
    		for (int i = 1; i <=10 ; i++) {
    			try {
    				Thread.sleep((int)Math.random()*300);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			clerk.getProduct();//从店员取走整数
    		}
    	}
    	
    }

    例子3:购票窗口实现票数同步

    package com.direct.demo;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ThreadTicket {
    	public static void main(String[] args) {
    		Booking b1 = new Booking("军人售票口");
    		Booking b2 = new Booking("学生售票口");
    		Booking b3 = new Booking("老年人售票口");
    		Booking b4 = new Booking("网上售票口");
    		b1.start();
    		b2.start();
    		b3.start();
    		b4.start();
    	}
    }
    
    /*
     * 多窗口卖票系统。多线程
     * 票数为静态的,共享数据
     * synchronized(对象){}代码块中的内容是加锁的,
     * 即当一个线程在使用时,其他线程不可以进入。
     * 使得共享资源数据的安全。
     */
    class Booking extends Thread{
    	public  Booking(String name){
    		super(name);
    	}	
    	static  int ticket = 50;//票数共50张
    	Lock lock = new ReentrantLock();//明锁

    /*
    * ReentrantLock根据传入构造方法的布尔型参数实例化出Sync的实现类FairSync和NonfairSync
    * ,分别表示公平的Sync和非公平的Sync。
    * 由于ReentrantLock我们用的比较多的是非公平锁

    ReentrantLock 和synchronized 均为重入锁

    * 1. ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。

    2. ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。

    3. ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。

     对ReentrantLock的可重入锁这篇博客使用简单的例子进行讲解,  http://blog.csdn.net/yanyan19880509/article/details/52345422

    	 * Lock是个接口,只能实例化它的子类
    	 * 明锁适合高并发,上万
    	 * 暗锁适合并发率不高时,效率高
    	 */
    	
    	//重写run方法,
    	public void run(){			
    			while(ticket>0){
    					synchronized (Booking.class) {
    						if (ticket>0) {
    							System.out.println(super.getName()+"窗口---->卖出的车票号No."+ticket);
    							ticket--;
    						}else {
    							System.out.println(super.getName()+"票已售罄!!!");
    						}				
    					 try {
    						sleep(100);//睡100毫秒,抛出多线程异常
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    			   }
    					/*lock.lock();//加锁,锁定以下代码
    					if (ticket>0) {
    						System.out.println(super.getName()+"卖票:"+ticket);
    						ticket--;
    					}else {
    						System.out.println(super.getName()+"票已售罄!!!");
    					}
    					try {
    						Thread.sleep(100);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					lock.unlock();//解锁
    */		}		
    		
    	}
    }

    例子4:线程中sleep()和wait()方法测试

    package com.direct.demo;
    
    public class TestSleepaWait {
    	public static void main(String[] args) {
    		new Thread(new Thread1()).start();
    		try {
    			Thread.sleep(5000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		new Thread(new Thread2()).start();
    	}
    	
    }
    
    class Thread1 implements Runnable{
    	public void run() {
    		synchronized (TestSleepaWait.class) {
    			System.out.println("Thread1 is start........");
    			System.out.println("Thread1 is wait..............");
    			try {
    				//调用wait方法,线程会放弃对象锁,进入等待对象的等待锁定池
    				TestSleepaWait.class.wait();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			System.out.println("Thread1 is go on........");
    			System.out.println("Thread1 is over!");			
    		}		
    	}		
    }
    
    class Thread2 implements Runnable{
    
    	@Override
    	public void run() {
    		synchronized (TestSleepaWait.class) {
    			System.out.println("Thread2 is enter..........");
    			System.out.println("Thread2 is sleep.......");
    			//只有针对对象调用notify()方法后本线程才进入对象锁定池
    			//准备获取对象进入运行状态
    			TestSleepaWait.class.notify();
    			//===============
    			//如果把上句注释掉。即对象锁调用了wait方法,但是没有调用notify
    			//程序就一致处于挂起状态
    			try {
    				Thread.sleep(5000);
    				//sleep方法暂停执行时间,让出CPU,监控状态保持,
    				//时间到 了就回复运行, 不会释放对象锁
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			System.out.println("Thread2 is going on..........");
    			System.out.println("Thread2 is over!!!!");
    		}
    		
    	}
    	
    } 

    例子5:sleep()实现对象存取值

    package com.direct.demo;
    
    public class ThreadCom {
    	public static void main(String[] args) {
    		Person person = new Person();
    		  new Thread(new Producer(person)).start();
    		  new Thread(new Consumer(person)).start();
    	}
    
    }
    
    class Person{
    	private String name = "张杰";
    	private String sex = "男";
    	public synchronized void put(String name,String sex){
    		this.name = name;
    		this.sex = sex;
    		try {
    			Thread.sleep(100);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    	//方法加锁
    	public synchronized void get(){
    		System.out.println(name+"----->"+sex);
    		try {
    			Thread.sleep(100);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    }
    
    class Consumer implements Runnable{
    	Person person;
    	public Consumer(Person person){
    		this.person = person;
    	}
    	public void run() {
    		while(true){
    			person.get();
    		}
    	}
    }
    
    class  Producer implements Runnable{
    	Person person;
    	public Producer(Person person){
    		this.person = person;
    	}
    	public void run() {
    		int i = 0;
    		while (true) {
    			if (i==0) {
    				person.put("谢娜", "女");
    			}else {
    				person.put("张杰", "男");
    			}
    			i = (i+1)%2;//奇数和偶数
    		}
    		
    	}
    	
    }   

    例子6:死锁发生条件

    在写代码时要避免死锁

    package com.direct.demo;
    
    public class DeadLock {
    	public static void main(String[] args) {
    		ThreadLock tl = new ThreadLock(true);
    		ThreadLock tl2 = new ThreadLock(false);
    		new Thread(tl).start();
    		new Thread(tl2).start();
    	}
    }
    
    /*
     * 死锁的产生条件:
     * 1、至少一个资源共享
     * 2、至少有一个线程(任务),必须持有资源,且等待获取别的线程持有的资源
     * 3、任务抢不到资源
     * 4、必须有无限循环
     * (1) 互斥条件:一个资源每次只能被一个进程使用。
     * (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
     * (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
     * (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
     * 举例说明:不可剥夺资源A、B,进程C、D
     * 不可剥夺资源:一个进程申请了之后,不能强制收回,只能进程结束之后自动释放。内存是可剥夺资源
     * 进程C申请了资源A,进程D申请了资源B。
     * 接下来进程C的操作需要用到资源B,进程D的操作需要用到资源A
     * 但是C、D都得不到资源,就引发了死锁
     */
    
    class Lock{
    	static Object lockOne = new Object();//资源A
    	static Object lockTwo = new Object();//资源B
    }
    
    
    class ThreadLock implements Runnable{
    	private boolean flag;
    	public ThreadLock(boolean flag){
    		this.flag = flag;
    	}
    	@Override
    	public void run() {
    		if(flag){
    			while (true) {
    				synchronized (Lock.lockOne) {
    					System.out.println(" this is lockOne");
    					synchronized (Lock.lockTwo) {
    						System.out.println("this is lockTwo");
    					}
    				}
    			}
    		}else {
    			while (true) {
    				synchronized (Lock.lockTwo) {
    					System.out.println(" 这是 lockTwo");
    					synchronized (Lock.lockOne) {
    						System.out.println("这是 lockOne");
    					}
    				}
    			}
    		}
    	}
    	
    	
    }
    
  • 相关阅读:
    DeepLearning.aiWeek1Convolution+model++Application
    搭建自己的git服务器
    Deep Neural Networks for Object Detection(翻译)
    VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGESCALE IMAGE RECOGNTION(翻译)
    windows 10下sublime text3环境的搭建以及配置python开发环境
    DeepLearning.aiWeek2Residual Networks
    DeepLearning.aiWeek4Deep Learning & Art: Neural Style Transfer
    同步&异步+阻塞&非阻塞(理解)
    VGGNet学习——实践
    Realtime MultiPerson 2D Pose Estimation using Part Affinity Fields(理解)
  • 原文地址:https://www.cnblogs.com/nn369/p/8043303.html
Copyright © 2011-2022 走看看