多线程
明天咱们来聊聊多多线程
- 多线程创立形式
- 通过继承Thread
- 创立通过接口Runnable创立
- 线程平安
- 同步代码块
- 同步办法
- Lock锁
- 线程状态
Thread与Runnable 创立
Thread
public class MyThread extends Thread { public MyThread(String name){ super(name); } public void run(){ for (int i = 0; i < 20; i++) { //getName()办法 来自父亲 System.out.println(getName()+i); } }}// 测试类 public class Demo { public static void main(String[] args) { System.out.println("这里是main线程"); MyThread mt = new MyThread("TR"); mt.start();//开启了一个新的线程 for (int i = 0; i < 20; i++) { System.out.println("MI:"+i); } }}
Runnable
public class MyRunnale implements Runnable{ @Override public void run(){ for(int i = 0 ; i < 20 ; i++){ System.out.println(Thread.cerrentThread().getName() + i); } }}// 测试类2 public class Demo02{ public static void mian(Stirng []args){ // 创立自定义类对象 线程工作对象 MyRunnable mr = new MyRunnable(); // 创立线程对象 Thread t = new Thread(mr,"Run对象"); t.start(); System.out.println("main的线程"); }}
Thread和Runnable区别:
如果一个类继承Thread,他就不适宜资源共享
,然而应用Runnable接口的话,则更容易实现资源共享
.
- 应用多个雷同代码
共享一个
资源 - 能够
防止
java中单继承的局限性 - 线程池中
只能
放入Runnable或Callble类线程,不能
间接放继承了Thread的类
线程平安
同步代码块: synchronized关键字 示意用于某个办法中的某个区块,履行互斥拜访
public class Ticket{ private int ticket = 100; Object lock = new Objcet();// 同步代码块 @Override public void run(){ // 买票口永恒开启 while(true){ synchronized(lock){ if (ticket > 0 ){ // 有票 try{ Thread.sleep(50); } catch(InterruptedException e){ e.printStackTrace(); } String name = Thread.currentThread().getName(); System.out.println( name + "正在买" + ticket-- ); } } } }}
同步办法: 应用synchronzied润饰的办法,就是同步办法,保障A线程执行别的线程等着。
public class Ticket implements Runnable{ private int ticket = 100; /* * 执行卖票操作 */ @Override public void run() { //每个窗口卖票的操作 //窗口 永远开启 while(true){ sellTicket(); } } /* * 锁对象 是 谁调用这个办法 就是谁 * 隐含 锁对象 就是 this */ //同步办法 public synchronized void sellTicket(){ if(ticket>0){//有票 能够卖 //出票操作 //应用sleep模仿一下出票工夫 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //获取以后线程对象的名字 String name = Thread.currentThread().getName(); System.out.println(name+"正在卖:"+ticket‐‐); } }}
Lock锁
Lock锁也被称为同步锁.办法如下:lock:
加同步锁。unlock:
开释同步锁。
public class Ticket implements Runnable{ private int ticket = 100; Lock lock = new ReentrantLock(); /* * 执行卖票操作 */ @Override public void run() { //窗口 永远开启 while(true){ lock.lock(); // 加同步锁 if(ticket>0){//有票 能够卖 //出票操作 //应用sleep模仿一下出票工夫 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } //获取以后线程对象的名字 String name = Thread.currentThread().getName(); System.out.println(name+"正在卖:"+ticket‐‐); } lock.unlock(); // 开释同步锁 } }}
线程状态
/* * 线程状态 * * new 新建 * Runnable 可运行{ * 线程能够在java虚拟机中运行的状态,可能正在运行本人代码,也可能没有, * 这取决于操作系统处理器。 * } * Blocked 锁阻赛 { * 一个线程想要取得一个对象锁,而对象锁正在被别一个线程所持有,线程就进入了Blocked * 当线程领有对象锁,就变成 Runnable * } * Waiting 无线期待 { * 一个线程期待别一个线程(唤醒) 此线程就进入无线期待的状态 必须要别一个线程唤醒 * * } * TimedWaiting 计时期待 { * 同是 Waiting状态, 但他有几个办法有超时参数,当你调用它们就进入TimedWaiting状态 * 这个状态会有唤醒告诉 * } * Teminated()被终止 { * 因为run办法失常退出而死亡 * } * * */