zoukankan      html  css  js  c++  java
  • day11(多线程,唤醒机制,生产消费者模式,多线程的生命周期)

    A:进程:

        进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。

    B:线程:

         线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

    C:简而言之:

        一个程序运行后至少有一个进程,一个进程中可以包含多个线程

    线程实现

      实现的两种方式

        继承Thread

    public class MyThread extends Thread{
    	@Override
    	public void run() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println(getName()+":"+i);
    		}
    	}
    }
    

      测试类

    public class MyThread02 extends Thread {
    	@Override
    	public void run() {
    		MyThread t=new MyThread();//直接创建对象就能创建一个线程
    	        t.start();
    	}
    }    
    

      

        实现Runnable

    public class MyThreadImp implements Runnable{	
    	int num;
    	public MyThreadImp(int num){
    		this.num=num;
    	}
    	@Override
    	public void run() {
    		for (int i = 0; i < 5; i++) {
    			System.out.println(Thread.currentThread().getName()+num++);
    		}
    	}
    }
    

      测试类

    public class Test01 {
    	public static void main(String[] args) {
    		MyThreadImp mt=new MyThreadImp(10);
    		Thread t=new Thread(mt);
    		t.setName("张三");
    		t.start();
    		Thread t1=new Thread(mt);
    		t1.setName("李四");
    		t1.start();
    	}
    }
    

      

    多线程安全问题

      线程的安全性==数据的安全性

          ①是否存在多线程

          ②是否有共享数据

          ③是否有多条语句执行共享数据

      解决办法  synchronized同步锁

    eg:

    public class MyThread implements Runnable {
    	int tickets;
    	public MyThread(int tickets) {
    		this.tickets = tickets;
    	}
    	Object o = new Object();
    	@Override
    	public void run() {
    		while (true) {
    			synchronized (o) {
    				if (tickets > 1) {
    					System.out.println(Thread.currentThread().getName() + "-"
    							+ tickets--);
    				}
    			}
    		}
    
    	}
    }
    

      测试类

            MyThread mt=new MyThread(100);
    		Thread t=new Thread(mt);
    		t.setName("窗口1");
    		Thread t2=new Thread(mt);
    		t2.setName("窗口2");
    		Thread t3=new Thread(mt);
    		t3.setName("窗口3");
    		t.start();
    		t2.start();
    		t3.start();            
    

      如果不给线程加锁  则会产生数据乱掉,可能会产生-1;结果我们不可预测。

    在方法中给加锁,另一种方法则是给方法加锁eg:

    public class MyThread01 implements Runnable{
    	 static int tickets=100;
    	public MyThread01(int tickets) {
    		this.tickets = tickets;
    	}
    	@Override
    	public void run() {
    		while (true) {
    				method01();
    		}
    
    	}
    	private synchronized void method01() {
    		if (tickets >= 1) {
    			System.out.println(Thread.currentThread().getName() + "-"
    					+ tickets--);
    		}
    	}
    }
    

      

    抢红包案列:

    public class MyThread implements Runnable {
    
    	int money;
    	int count;
    
    	public MyThread(int money, int count) {
    		this.money = money;
    		this.count = count;
    	}
    
    	@Override
    	public void run() {
    		// 产生一个随机数
    			method();
    	}
    
    	private synchronized void method() {
    		if (count > 1 && money != 0) {
    			Random r = new Random();
    			double d = (r.nextInt(money) + 1);
    			money -= d;
    			System.out.println(Thread.currentThread().getName() + ":" + d);
    			count--;
    		} else {
    			System.out.println(Thread.currentThread().getName() + ":"
    					+ money);
    		}
    	}
    
    }
    

      测试类

    public class Hongbao {
    	public static void main(String[] args) {
    		MyThread mt=new MyThread(10,3);
    		Thread t=new Thread(mt);
    		t.setName("张三");
    		t.start();
    		t.setPriority(10);
    		Thread t1=new Thread(mt);
    		t1.setName("李四");
    		t1.start();
    		Thread t2=new Thread(mt);
    		t2.setName("李");
    		t2.start();
    	}
    }
    

      

    生产消费者模式:

        解释了多线程唤醒机制(notify()是Object中的方法)

    使用多线程中的案列

      产品  由于只是做测试使用 没有写全

    public class Student {
    	String  name;
    	int age;
    	boolean flag;
    }
    

      

        生产者 如果消费者没有消费产品 则进行等待 ,只有消费了生产者才会进行生产

    public class StThread implements Runnable {
    	private Student s;
    	public StThread(Student s) {
    		this.s = s;
    	}
    	int x;
    	@Override
    	public void run() {
    		while (true) {
    			synchronized (s) {
    				if (s.flag) {//如果flag=true;则说明已经有对象了  还没有消费,则进行等待
    					try {
    						s.wait();
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}// 等待
    				}
    				if (x % 2 != 0) {
    					s.name = "赵云";
    					s.age = 44;
    				} else {
    					s.name = "张飞";
    					s.age = 22;
    				}
    				x++;
    				s.flag=true;//修改标记
    				s.notify();//唤醒
    			}
    		}
    	}
    }
    

      

        消费者  如果消费者没有东西消费 则会进行等待  有了东西,才会进行消费

    public class GtThread implements Runnable {
    	private Student s;
    	public GtThread(Student s) {
    		this.s = s;
    	}
    	@Override
    	public void run() {
    		while (true) {//保证一直在等待中
    			synchronized (s) {
    				if (!s.flag) {//flag=false则进行等待  等待学生对象的产生
    					try {
    						s.wait();//线程等待
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    				System.out.println(s.name + ":" + s.age);
    				s.flag=false;
    				s.notify();
    			}
    		}
    	}
    }
    

      

    测试类

    public class Test {
    	public static void main(String[] args) {
    		Student s=new Student();
    		StThread st=new StThread(s);
    		GtThread gt=new GtThread(s);
    		Thread t1=new Thread(st);
    		Thread t2=new Thread(gt);
    		t1.start();
    		t2.start();
    	}
    }
    

      输出结果

    输出结果:
    赵云:44
    张飞:22
    赵云:44
    张飞:22
    赵云:44
    张飞:22
    赵云:44
    .......一直交替循环下去
    

      

     线程的生命周期

  • 相关阅读:
    scheme资料
    lisp 资料
    linux input 文章
    qt 键盘驱动分析
    表达式模板 (C++学习)
    qt 键盘插件(mine)
    qt 私有实现导致plugin 加载 提示 undefined symbol
    Visual C++ 8.0对象布局的奥秘:虚函数、多继承、虚拟继承
    linux内核input子系统解析
    qt 键盘 插件
  • 原文地址:https://www.cnblogs.com/fjkgrbk/p/moreProgram.html
Copyright © 2011-2022 走看看