多线程重要点和示例

多线程

什么是多线程:

​ 多任务多条路径多个顺序流同时执行就是多线程

多线程的优点:

​ 提高效率,同时执行

多线程的缺点:

​ 复杂

多线程的创建方式:

  1. 继承Thread类,重写run()方法,run方法中定义多线程的线程体

    	/**
     * 线程创建方式
     * @author zhuch
     *
     */
    public class ThreadTest extends Thread{
    
    	@Override
    	public void run() {
    		for (int i = 0; i < 5; i++) {
    			System.out.println("犯困");
    		}
    		
    	}
    	
    	
    	
    	
    	public static void main(String[] args) throws InterruptedException {
    		//创建
    		ThreadTest t=new ThreadTest();
    		//开启
    		t.start();
    		
    		// TODO Auto-generated method stub
    		for (int i = 0; i < 5; i++) {
    			System.out.println("瞌睡");
    			Thread.sleep(100);
    		}
    	}
    
    }
    
  2. 实现Runnable接口,重写run()方法

    推荐:

    1. 避免单继承的局限性
    2. 实现资源共享
    /**
     * 线程创建方式2
     * @author zhuch
     *
     */
    public class RunnableTest implements Runnable{
    
    	
    
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		for (int i = 0; i < 5; i++) {
    			System.out.println("梦想");
    		}
    	}
    	
    	
    	
    	public static void main(String[] args) throws InterruptedException {
    		// TODO Auto-generated method stub
    		Thread t=new Thread(new RunnableTest());
    		
    		t.start();
    		
    		
    		for (int i = 0; i < 5; i++) {
    			System.out.println("远方");
    			Thread.sleep(10);
    		}
    	}
    
    }
    
  3. 实现Callable接口,重写call方法

    优点:

    1. 可以抛出异常
    2. 接收返回值

    缺点:使用麻烦

线程安全:

  • 多线程同时操作同一份资源才有可能会出现线程不安全的问题,需要控制安全

同步锁:

synchronized
  • 为了让线程排队执行{}中的代码

  • 同步块 synchronized(锁的内容){同步的代码范围}

  • 锁的内容: this 类.class 资源(成员变量)

  • 类.class 相当于把这个类,类的所有内容锁住了,类的所有对象都锁住

  • this 当前调用成员方法的对象,相当于把这个对象的所有资源都锁住了,可以只锁资源

  • 资源: 成员变量,一定要是自定义的引用数据类型的对象

  • 锁的范围:{}->中代码的范围

  • 注意:

    • 锁的范围太大,效率低
    • 锁的范围太小,锁不住
    • 锁不变的内容
    /**
     * 多线程打印12A23B45C67D...直到字母打印完结束
     * @author zhuch
     *
     */
    
    public class Test {
    	
    	public static void main(String[] args) {
    		//创建对象
    		PrintTest pr=new PrintTest();
    		//开启线程
    		new Thread(new Number(pr)).start();
    		new Thread(new CharTest(pr)).start();
    		
    	}
    
    }
    
    //行为
    class PrintTest{
    	//成员变量
    	boolean flag=false;
    	int num=1;
    	char num1='A';
    	//打印数字(同步块)
    	public synchronized void number() {
    		if(flag==true) {
    			try {
    				this.wait();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}else {
    			try {
    				Thread.sleep(200);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			
    			for(int i=0;i<2;i++) {
    				if(num==53) {
    					return;
    				}
    				System.out.print(num++);
    			}
    			
    			flag=true;
    			this.notify();
    		}
    	}
    	
    	//打印字母(同步块)
    	public synchronized void charTest() {
    		if(flag==false) {
    			try {
    				this.wait();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}else {
    			try {
    				Thread.sleep(200);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			System.out.print((char)(num1++));
    			flag=false;
    			this.notify();
    		}
    	}
    	
    }
    //数字类实现Runnable接口重写run方法
    class Number implements Runnable{
    	PrintTest pr=null;
    	
    	
    	
    	public Number(PrintTest pr) {
    		super();
    		this.pr = pr;
    	}
    
    
    
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		while(true) {
    			pr.number();
    		}
    	}
    	
    }
    //字母类实现Runnable接口重写run方法
    class CharTest implements Runnable{
    	PrintTest pr=null;
    	
    	
    	
    	public CharTest(PrintTest pr) {
    		super();
    		this.pr = pr;
    	}
    
    
    
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		while(true) {
    			pr.charTest();
    		}
    	}
    	
    }
    
    public class SynchronizedTest implements Runnable{
    	Ticket ticket=new Ticket();
    	
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		SynchronizedTest syn=new SynchronizedTest();
    		new Thread(syn,"A").start();
    		new Thread(syn,"B").start();
    		new Thread(syn,"C").start();
    	}
    
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		while(true) {
    			synchronized(this) {
    				if(ticket.num<=0) {
    					break;
    				}
    				try {
    					Thread.sleep(2);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				System.out.println(Thread.currentThread().getName()+"正在购买第"+ticket.num-- +"张票");
    			}
    		}
    	}
    
    }
    class Ticket{
    	int num=100;
    }
    

线程状态:

  • 新生状态:new创建一个线程的时候

  • 就绪状态:start(),线程会进入就绪队列,等待cpu的调度

  • 运行状态:cpu调用分配时间片给线程,线程就会运行

  • 阻塞状态:sleep()…

  • 终止状态:线程结束了

  • 一个线程一旦就如到阻塞状态,阻塞解除之后,不会马上恢复到运行,会恢复到就绪状态,再次等待cpu的调度

  • 一个线程一旦进入终止状态,再也不会恢复

  • 如何一个线程进入就绪状态:

    • 1.start()
    • 2.阻塞解除
    • 3.线程切换,被切换的线程会恢复就绪状态
    • 4.yield() 礼让线程
  • 进入阻塞状态的方式:

    • 1.sleep

    • 2.wait

    • 3.join

  • 如何控制一个线程终止:

    • 1.stop…不推荐
    • 2.通过表示判断
    • 3.正常执行结束
  • sleep(): 线程睡眠

    • 1)模拟网络延迟
    • 2)放大问题的可能性
    • 让出cpu的资源,不会让出对象的锁(保证资源睡觉),指定休息多少毫秒
public class StateTest implements Runnable{

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		StateTest sta=new StateTest();
		new Thread(sta,"A").start();
		new Thread(sta,"B").start();
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		Thread t=new Thread(()-> {
			for (int i = 0; i < 20; i++) {
				System.out.println("插队");
				try {
					Thread.sleep(5);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		
		
		t.start();
		try {
			t.join();//方法插队
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println(Thread.currentThread().getName()+"开始执行");
		Thread.yield();//礼让线程
		System.out.println(Thread.currentThread().getName()+"结束执行");
		
	}
	

}

Thread中 getState() 获取某个线程的状态

线程优先级:

  •  提高先执行的概率
    
  • getPriority() 返回该线程的优先级
  • setPriority(int newPriority)改变这个线程的优先级
    • 1~10 1最小 10最大 默认是5
public class StateDemo02 {
	public static void main(String[] args) {
		Thread th=new Thread(()->{
			for(int i=0;i<=10;i++){
				if(i==5){
					try {
						Thread.sleep(5);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		});
		th.setPriority(10);
		System.out.println(th.getPriority());
		
		System.out.println("th线程状态"+th.getState());
		th.start();
		
		while(true){
			Thread.State state=th.getState();
			System.out.println(state);
			if(state ==Thread.State.TERMINATED){
				break;
			}
			try {
				Thread.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
发布了13 篇原创文章 · 获赞 13 · 访问量 502

猜你喜欢

转载自blog.csdn.net/Rabbit_white_/article/details/104036310
今日推荐