2019-7-18 [JavaSE] 线程-新建/就绪/运行/阻塞/死亡 主线程 子线程-三种运行 线程优先级 中断-sleep/join/yield 同步 锁 synchronized/lock

1.线程

进程: 内存中运行的一个应用程序。
线程:进程中的执行流程
多线程: 一个进程中 由两个或两个以上这样的并发的执行流程。

2.线程状态

在这里插入图片描述
线程的生命周期:
在这里插入图片描述

1.新建

   Thread 或 Thread子类
   new  Thread();

2.就绪

 start()   
等待cpu的调用执行

3.运行

cpu调用执行了此线程。

4.阻塞

运行的线程 由于 某种原因 暂停了 cpu的调用执行。
1)sleep: 等待 (时间毫秒long)
线程A 调用了sleep()方法 ,那么线程A就处于了 阻塞状态, 当等待的时间超时了,
那么线程A才能恢复到 就绪状态 ,等待cpu调用执行,一旦cpu调用执行了,那么就
处于 运行状态。
join: 让一些线程先执行完
当t1 调用 join()方法了,那么 t2线程需要等待 t1线程都执行完 ,才能恢复到 就绪状态,
t2在等待的过程中就是阻塞状态。
2)同步
排队
3) wait 等待

5.死亡

3.线程

1.主线程

 最前 被 启动的线程 就是 主线程。
 主线程的任务 在 main()中。

2.子线程

任务在 :run()中
在这里插入图片描述

方式一:继承Thread类

子线程的默认名称: Thread-0

class SubThread1 extends Thread{
	// 给子线程起名字
	SubThread1(String name){
		super(name);
	}
	@Override
	public void run() {
		for(int i = 1; i <= 3; i++) {
			System.out.println(Thread.currentThread().getName() + ": " + i);
		}
	}
}
public class TestSubThread1 {
	public static void main(String[] args) {
		//创建一个线程对象
		SubThread1 t1 = new SubThread1("t1");
		//启动一个线程
		t1.start(); 	
	}
}

方式二:实现Runnable接口

class SubThread2 implements Runnable{
	@Override
	public void run() {
		for(int i = 1; i <= 3; i++) {
			System.out.println(Thread.currentThread().getName() + ":" + i);
		}
	}	
}
public class TestSubThread2 {

	public static void main(String[] args) {
		// 
		SubThread2 st = new SubThread2();
		//创建一个线程
		Thread t = new Thread(st,"t1");
		t.start();
	}
}

方式三:实现Callable接口*

class SubThread3 implements Callable<Integer>{

	@Override
	public Integer call() throws Exception {
		int sum = 0;
		for(int i =1; i <= 3 ;i++) {
			System.out.println(Thread.currentThread().getName()+":" + i);
			sum += i;
		}
		return sum;
	}
}
public class TestSubThread3 {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		SubThread3 sub = new SubThread3();
		// 接收返回值
		FutureTask<Integer> f = new FutureTask<>(sub);
		//
		Thread t = new Thread(f,"tt");
		t.start();
		//获得返回结果
		System.out.println(f.get());	
	}
}

区别

1.继承Thread类 ,那么 这个类 就成为了一个线程类。
实现接口的其他两种方式 ,这个类本身不是线程类,需要借助Thread类创建线程。
2.实现接口的方式区别:
在这里插入图片描述

4.线程的优先级

在这里插入图片描述
1 - 10
1 - 最小的
10 - 最高的

设置优先级

//		t1.setPriority(1);
//		t2.setPriority(10);

t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);

5.方法

1.interrupt()线程中断

sleep()和join()

当t1 线程 被 t2线程中断了 ,那么 t1 线程 进入到异常处理。

class Thread1 implements Runnable{
	public void run() {
		for(int i = 1; i <= 10; i++) {
			if( i == 5 ) {
				try {
					Thread.sleep( 1000);
				} catch (InterruptedException e) {
					System.out.println(Thread.currentThread().getName()+"进入到了异常处理");
				}
			}
			System.out.println(Thread.currentThread().getName()+":" + i);
		}
	}
}
public class TestInterrupt {

	public static void main(String[] args) {
		Thread1 tr1 = new Thread1();
		Thread t1 = new Thread(tr1,"t1");
		t1.start();
		t1.interrupt();// 中断t1 
	}
}

2.yield() 线程让步(了解)

Thread.yield()

class Thread2 implements Runnable{
	public void run() {
		for(int i = 1; i <= 10; i++) {
			if( i == 5 && Thread.currentThread().getName().equals("t1") ) {
				Thread.yield();//让步
			}
			System.out.println(Thread.currentThread().getName()+":" + i);
		}
	}
}
public class TestYield {

	public static void main(String[] args) {
		Thread2 tr2 = new Thread2();
		Thread t1 = new Thread(tr2,"t1");
		Thread t2 = new Thread(tr2,"t2");
		
		t1.setPriority(1);
		t2.setPriority(10);
		
		t1.start();
		t2.start();
	}
}

6.线程同步

在这里插入图片描述
在这里插入图片描述

同步阻塞

1.获得锁

当线程 执行到 同步代码块 或 同步方法中的代码时,需要获得锁;

2.获得了锁

当线程A获得 锁成功,就可以执行同步代码块或同步方法中的代码了,
在执行的过程中,其他线程 是不能执行 此对象的同步代码块或同步方法中的代码,
但是 可以执行 其他 对象 的 同步代码块 或 同步方法的代码。

3.释放锁

1)同步代码块 或 同步方法的代码 正常执行完;
2)同步代码块 或 同步方法的代码 遇到了没有能处理的异常中断了程序;
3)同步代码块 或 同步方法的代码 return ,break;  结束了代码块或方法;
4)同步代码块 或 同步方法的代码 wait().

以上四种方式释放锁

法一
class Bank implements Runnable{
	private int money = 0;
	//存一次钱的方法 锁对象 this,synchronized在这里添加
	synchronized public void setMoney() {
		this.money  += 100;
		System.out.println(Thread.currentThread().getName()
				+ "存了100,余额:" + this.money);
	}
	public void run() {
		for(int i = 1; i <= 3; i++) {
				this.setMoney();			
		}
	}
}
public class TestBank {

	public static void main(String[] args) {
		Bank bank = new Bank();
		
		Thread zhangsan = new Thread(bank,"张三");
		Thread lisi = new Thread(bank,"李四");
		zhangsan.start();
		lisi.start();
	}
}
法二
class Bank implements Runnable{
	private int money = 0;
	private int count = 0;
	//存
	 public void setMoney() {
		this.money += 100;
		count ++;
		System.out.println(Thread.currentThread()
				.getName()+"剩"+money+","+count);
	}
	public void run() {
		for (int i = 1; i <= 3; i++) {
		//synchronized在这里添加
			synchronized (this) {
				this.setMoney();	
			}		
		}
	}
}

7.ReentrantLock

在这里插入图片描述

法一

class Bank1 implements Runnable{
	private int money = 0;
	// 公平锁
	ReentrantLock  lock = new ReentrantLock();
	//存一次钱的方法 锁对象 this
	public void setMoney() {
		try {
			lock.lock();// 获得锁
			this.money  += 100;
			System.out.println(Thread.currentThread().getName()
					+ "存了100,余额:" + this.money);
		}finally {
			lock.unlock();// 释放锁
		}
	}
	public void run() {
		for(int i = 1; i <= 3; i++) {
				this.setMoney();		
		}
	}
}
public class TestLock {

	public static void main(String[] args) {
		Bank1 bank = new Bank1();
		
		Thread zhangsan = new Thread(bank,"张三");
		Thread lisi = new Thread(bank,"李四");
		zhangsan.start();
		lisi.start();
	}
}

法二

class Bank implements Runnable{
	private int money = 0;
	private int count = 0;
	ReentrantLock lock = new ReentrantLock();
	//存
	 public void setMoney() {
		lock.lock();
		this.money += 100;
		count ++;
		System.out.println(Thread.currentThread()
				.getName()+"剩"+money+","+count);
		lock.unlock();
	}
	public void run() {
		for (int i = 1; i <= 3; i++) {
				this.setMoney();	
		}
	}
}

synchronized 和 Lock的区别

1.synchronized 是一个关键字 使用简单;
Lock 需要创建对象 ,显示获得锁 和 显示 释放锁;
2.synchronized 没有 明显的 获得锁 或 释放锁;
Lock可以 显示的获得锁和释放锁;
3.Lock 提供了更多的方法。提供了更多的功能。

8.编写:多线程

加粗样式

class SubThread5 implements Runnable{
	@Override
	public void run() {
		for(int i = 1; i <= 10; i++) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + ":" + i);
		}
	}	
}
public class TestSubThread5_exam {

	public static void main(String[] args) {
		SubThread5 sub = new SubThread5();
		new Thread(sub,"t1").start();
		new Thread(sub,"t2").start();
	}
}

9.注意:

1.Callable有返回值
2.在线程少时sy和lock一样,线程多的时候用lock可以提升性能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值