线程的创建方式、安全、状态

多线程 今天我们来聊聊多多线程

  1. 多线程创建方式
  • 通过继承Thread
  • 创建通过接口Runnable创建
  1. 线程安全
  • 同步代码块
  • 同步方法
  • Lock锁
  1. 线程状态
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接口的话,则更容易实现资源共享.
  1. 使用多个相同代码共享一个资源
  2. 可以避免java中单继承的局限性
  3. 线程池中只能放入Runnable或Callble类线程,不能直接放继承了Thread的类
线程安全 同步代码块: synchronized关键字 表示用于某个方法中的某个区块,实行互斥访问
public class Ticket{ private intticket = 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方法正常退出而死亡 * } * * */

    推荐阅读