Java多线程

线程概念

一:程序 进程 线程
  1. 程序:Program 编写的代码,指令集,静态概念
  2. 进程:Process 操作系统调度程序,动态概念  作为资源分配的单位
  3. 线程:Thread 进程内多条执行路径 轻量级进程 调度和执行的单位 线程使用的资源是它所属进程的资源 只能共享资源 除CPU外不会为线程分配内存

线程创建

一:继承Thread + 重写run()方法
Rabbit.java
public class Rabbit extends Thread {
	public void run() {
		for(int i=0; i<5; i++) {
			System.out.println("Rabbit: " + i);
		}
	}
}
启动:创建子类对象 + 调用子类对象.start()方法
RabbitApp.java
public class RabbitApp {

	public static void main(String[] args) {
		Rabbit rabbit = new Rabbit();
		//Tortoise tortoise = new Tortoise();
		rabbit.start();
		//tortoise.start();
	}
}
二:实现Runnable接口 + 重写run()方法
Programmer.java
public class Programmer implements Runnable {

	@Override
	public void run() {
		for(int i=0; i<5; i++) {
			System.out.println("Programmer: " + i);
		}
	}
}
启动:创建真实角色
       创建代理角色:Thread + 对真实角色的引用
       代理角色.start()

ProgrammerApp.java

public class ProgrammerApp {

	public static void main(String[] args) {
		Programmer programmer = new Programmer();
		Thread proxy = new Thread(programmer);
		proxy.start();

		//for(int i=0; i<5; i++) {
		//	System.out.println("main: " + i);
		//}
	}
}

推荐:使用接口

  1. 避免单继承局限性
  2. 便于共享资源

三:创建Callable实现类 + 重写call()方法 可以抛检查时异常 前面的run()方法是不能抛异常的

线程状态

一:线程状态转换图


新生状态:用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)
就绪状态:处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列,等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为”CPU调度“。一旦获得CPU,线程就进入运行状态并自动调用自己的run方法。
运行状态:在运行状态的线程执行自己的run方法中,代码直到调用其他方法而终止,或等待某资源而阻塞或完成任务而死亡。如果过在给定的时间片内没有执行结束,就会被系统给换下来回到等待执行状态。
运行状态:处于就绪状态的线程获得CPU时间片后,进入运行状态,真正开始执行run方法。
阻塞状态:处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续执行。
死亡状态:死亡状态是线程生命周期中的最后一个阶段。线程死亡的原因有两个。一个是正常运行的线程完成了它的全部工作;另一个是线程被强制性的终止,如通过执行stop或destroy方法来终止一个线程【不推荐使用这两个方法。前者会产生异常,后者是强制终止,不会释放锁。】

停止线程

一:自然终止 线程体自然执行完毕
二:外部干涉
  1. 线程体中定义线程体使用的标识
  2. 线程体使用该标识
  3. 提供对外的方法改变该标识
  4. 外部根据条件调用该方法即可
StopDemo01.java
public class StopDemo01 {

	public static void main(String[] args) {
		Study study = new Study();
		Thread thread = new Thread(study);
		thread.start();
		for(int i=0; i<100; i++) {
			if(i==50) {
				study.stop();
			}	
			System.out.println("main thread->" + i);
		}
	}
	
}
class Study implements Runnable {
	private boolean flag = true;
	
	public void run() {
		while(flag) {
			System.out.println("study thread...");
		}
	}
	
	public void stop() {
		this.flag = false;
	}
}


线程阻塞

一:join 合并线程
JoinDemo01.java
public class JoinDemo01 extends Thread {

	public static void main(String[] args) throws Exception {
		JoinDemo01 joindemo01 = new JoinDemo01();
		Thread t = new Thread(joindemo01);
		t.start();
		
		for(int i=0; i<100; i++) {
			if(i==50) {
				t.join(); //main阻塞
			}
			System.out.println("main thread..." + i);
		}
	}

	public void run() {
		for(int i=0; i<100; i++) {
			System.out.println("join thread..." + i);
		}
	}
}<strong>
</strong>
二:yield 暂停自己的线程 static
YeildDemo01.java
public class YieldDemo01 extends Thread {

	public static void main(String[] args) {
		JoinDemo01 joindemo01 = new JoinDemo01();
		Thread t = new Thread(joindemo01);
		t.start();
		
		for(int i=0; i<100; i++) {
			if(i%10==0) {
				Thread.yield(); //暂停本线程main
			}
			System.out.println("main thread..." + i);
		}
	}

	public void run() {
		for(int i=0; i<100; i++) {
			System.out.println("yield thread..." + i);
		}
	}
}
三:sleep 休眠,不释放锁 static
  1. 与时间相关:倒计时
  2. 模拟网络延时
SleepDemo01.java
public class SleepDemo01 {

	public static void main(String[] args) throws Exception {

		int num = 10;
		while(num>=0) {
			Thread.sleep(1000);
			System.out.println(num);
			num--;
		}
	}
}

线程基本信息

Thread.currentThread() //当前线程 static
setName() //设置名称
getName() //获取名称
isAlive() //判断状态
优先级:概率大小,不是绝对的先后顺序
setPriority() //设置优先级大小
getPriority() //获取优先级

MyThready.java

public class MyThread implements Runnable {
	private boolean flag = true;
	private int num = 0;
	
	public void run() {
		while(flag) {
			System.out.println(Thread.currentThread().getName() + "->" + num);
			num++;
		}
	}
	
	public void stop() {
		this.flag = !this.flag;
	}
}
InfoDemo01.java
public class InfoDemo01 {

	public static void main(String[] args) throws Exception {
		MyThread mythread = new MyThread();
		Thread proxy = new Thread(mythread);
		proxy.setName("test");
		
		System.out.println(proxy.getName());
		System.out.println(Thread.currentThread().getName());
		
		proxy.start();
		Thread.sleep(100);
		mythread.stop();
	}
}
InfoDemo02.java
package com.cho3en1.thread.info;

public class InfoDemo02 {

	public static void main(String[] args) throws Exception {
		MyThread mythread1 = new MyThread();
		MyThread mythread2 = new MyThread();
		
		Thread t1 = new Thread(mythread1);
		Thread t2 = new Thread(mythread2);
		
		t1.setPriority(Thread.MAX_PRIORITY);
		t2.setPriority(Thread.MIN_PRIORITY);
		
		t1.start();
		t2.start();
		
		Thread.sleep(200);
		mythread1.stop();
		mythread2.stop();
	}

<h2>}</h2>

线程同步与锁定

同步:并发 多个线程访问同一份资源 确保资源安全 
synchronized -> 同步

一:同步块
synchronized(引用类型|this|类.class) {
}

二:同步方法
synchronized 
SynDemo01.java
public class SynDemo01 {
	
	public static void main(String[] args) {
		Web12306 w = new Web12306();
		
		Thread p1 = new Thread(w, "黄牛1");
		Thread p2 = new Thread(w, "黄牛2");
		Thread p3 = new Thread(w, "黄牛3");
		
		p1.start();
		p2.start();
		p3.start();
		
	}
}

class Web12306 implements Runnable {
	private boolean flag = true;
	private int num = 50;
	
	@Override
	public void run() {
		while(flag) {
			test1();
		}
	}
	
	public synchronized void test1() {
		if(num<=0) {
			flag = false;
			return;
		}
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "抢到了" + num--);
	}
}

三:死锁
SynDemo02.java
public class SynDemo02 {

	public static void main(String[] args) {
		Test t1 = new Test();
		Test t2 = new Test();
		t1.flag = true;
		t2.flag = false;
		Thread proxy1 = new Thread(t1);
		Thread proxy2 = new Thread(t2);
		proxy1.start();
		proxy2.start();
	}

}

class Test implements Runnable {
	public boolean flag; 
	
	static Object goods = new Object();
	static Object money = new Object();
	
	public void run() {
		while(true) {
			test();
		}
	}
	
	public void test() {
		if(flag == true) {
			synchronized (goods) {
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (money) {
					System.out.println("一手给钱");
				}
			}	
		}
		if(flag == false) {
			synchronized (money) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (goods) {
					System.out.println("一手给货");
				}
			}
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值