1什么是线程
进程是程序执行的一次过程,它是一个动态的概念,是系统资源分配的单位,通常一个进程中可以包含若干个线程,线程就是独立执行的路径。线程的执行存在优先权问题
2java中线程的创建
(1)继承Thread类,重写run方法,run方法中编写线程执行体,创建线程对象,调用start()方法启动线程
(2)实现Runnable接口,实现runnable接口,重写run方法,创建线程对象,通过thread启动线程
(3)实现Callable接口(用的比较少)
可以定义返回值,可以抛出异常
多线程的使用是不安全的:多个线程操作同一个资源,线程不安全,数据出现紊乱
(1)解决线程并发的问题
3静态代理模式
(1)真实对象和代理对象都必须实现同一个接口
(2)代理对象必须要代理真实角色
(3)好处:代理对象可以代理真实对象做不了的事情,真实对象做自己的事情。
(4)实现runnable也是类似使用的静态代理模式
public class ThreadTestOne extends Thread { public static void main(String[] args) { StaticPeople staticPeople = new StaticPeople(new You()); staticPeople.Marray(); } interface Marray{ void Marray(); } } class You implements ThreadTestOne.Marray { @Override public void Marray() { System.out.println("我要结婚了"); } } class StaticPeople implements ThreadTestOne.Marray{ private You target; // private ThreadTestOne.Marray target; public StaticPeople(You target){ this.target = target; } @Override public void Marray() { before(); this.target.Marray(); after(); } private void before() { System.out.println("之前"); } public void after(){ System.out.println("之后"); } }
4停止线程(jdk中让线程停止的方法不推荐使用)
(1)利用自己写一个方法让线程停止
public class ThreadStop implements Runnable { //定义一个标识 private Boolean flag = true; @Override public void run() { while (flag){ System.out.println("线程开始执行了"); } } public static void main(String[] args) { ThreadStop threadStop = new ThreadStop(); new Thread(threadStop).start(); for (int i = 0; i < 1000; i++) { System.out.println("main方法的线程执行"+i); if(i==900){ threadStop.stop(); System.out.println("线程停止了"); } } } public void stop(){ this.flag = false; } }
5sleep让线程休眠,指定当前线程的休眠时间
(1)模拟网络延时:用来放大问题的发生性
(2)模拟倒计时:
public static void main(String[] args) { try { tenDown(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void tenDown() throws InterruptedException { int num = 10; while (true){ Thread.sleep(1000); System.out.println(num--); if(num<0){ break; } } } }
(3)线程礼让概念:让当前正在执行的线程暂停
//测试礼让线程 public class ThreadYield { public static void main(String[] args) { MyYield myYield = new MyYield(); new Thread(myYield, "A线程").start(); new Thread(myYield, "B线程").start(); } } class MyYield implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"开始执行了"); //线程礼让方法 (注意:礼让不一定成功,看CPU心情) Thread.yield(); System.out.println(Thread.currentThread().getName() + "结束了"); } }
(4)线程强制执行(join)(不推荐使用,造成阻塞)
public class ThreadJoin implements Runnable { public static void main(String[] args) { ThreadJoin threadJoin = new ThreadJoin(); Thread thread = new Thread(threadJoin); thread.start(); //主线程开始执行 for (int i = 0; i < 200; i++) { if (i == 198) { try { //线程开始插队了 thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(i + "主线程开始执行了"); } } @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println(i+"线程vip来了"); } } }
6线程的优先级问题(优先级高并不一定先执行,看cpu,一般的线程的级别为5)
(1)线程的优先级由数字1-10定义的
/** * The minimum priority that a thread can have. */ public final static int MIN_PRIORITY = 1; /** * The default priority that is assigned to a thread. */ public final static int NORM_PRIORITY = 5; /** * The maximum priority that a thread can have. */ public final static int MAX_PRIORITY = 10;
7守护线程和用户线程
(1)虚拟机必须确保用户线程的执行完毕
(2)虚拟机不用确保守护线程的执行,会在执行一段时间后停止
thread.setDaemon(true)//默认是false 表示用户线程
8线程同步机制(解决多个线程操作同一个资源的情况)
(1)处理多线程问题时,多个线程同时访问一个对象,并且某些线程想修改这个对象,这个时候我们就需要线程同步,线程同步其实就是一个等待机制,此时多个线程进入这个对象的等待池,形成队列,等前面的线程执行完毕后再执行。
(2)形成同步机制的条件:队列+锁 解决线程的安全问题
9同步方法和同步块:synchronized实现线程的同步,每个对象都有一把锁
(1)缺陷:锁一个大的方法会极大地影响性能
(2)synchronized默认锁的是this,对象的本身,synchronized(obj){}:同步块可以锁任意对象
(3)锁的对象一般是用于增删改的对象
10死锁的概念
(1)多个线程互相抱着对方需要的资源,形成僵持的状态
产生死锁的条件
11Lock(锁)
拥有了与synchronized相同的功能