线程的创建方式、安全、状态
多线程
今天我们来聊聊多多线程
- 多线程创建方式
- 通过继承Thread
- 创建通过接口Runnable创建
- 线程安全
- 同步代码块
- 同步方法
- Lock锁
- 线程状态
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的类
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方法正常退出而死亡
* }
*
* */
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量