JAVA---线程
来源:互联网 发布:新媒体矩阵建设方案 编辑:程序博客网 时间:2024/06/06 01:51
什么是线程?
线程是一个程序里的不同执行路径
一般的程序是从一个入口出发,沿着唯一的路径走到终点,而线程则使唯一的路径变成多条路径
以下是单线程操作
class A extends Thread{public void run(){while(true){System.out.println("hello world");}}}public class Thread1 {public static void main(String[]args){A aa=new A();aa.run();while(true){System.out.println("hello JAVA");}}}因为aa.run没有执行完毕,下面的while循环就不会执行,所以就是一直输出“hello world“
再看看多线程操作
class A extends Thread{public void run(){while(true){System.out.println("hello world");}}}public class Thread1 {public static void main(String[]args){A aa=new A();aa.start();while(true){System.out.println("hello JAVA");}}}
Thread中的start方法就是创建一个线程,并且自动调用run方法,直接调用run方法是不会创建一个线程的。
执行一个线程,其实就是执行一个线程里面的run方法,一个Thread对象不能调用两次start方法,否则会抛出异常。
单线程就是一条路径,从头到尾执行。
多线程就是有多条路径,每次都可以走不同的路径。
执行aa.start并不代表aa对象的线程就立刻执行,而是得到了能够被CPU执行的资格,也就是就绪的状态。!
创建线程的第二种方式:
class A implements Runnable{public void run(){while(true){System.out.println("hello world");}}}public class Thread2 {public static void main(String[]args){A aa=new A();Thread th=new Thread(aa);th.start();while(true){System.out.println("hello JAVA");}}}
Thread常用方法:
setName(String)设置名字
currentThread()返回正在执行线程的对象
getName()返回线程的名字
class A extends Thread{ public void run() { System.out.println("hello world"); System.out.println(Thread.currentThread().getName()); }}public class Thread1 { public static void main(String[]args) { A aa=new A(); aa.start(); System.out.println("hello JAVA"); System.out.println(Thread.currentThread().getName()); }}
class A extends Thread{public void run(){System.out.println("hello world");System.out.println(Thread.currentThread().getName());}}public class Thread1 {public static void main(String[]args){A aa=new A();aa.setName("123");aa.start();System.out.println("hello JAVA");System.out.println(Thread.currentThread().getName());}}
Thread的sleep方法
sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
要捕获异常!
class A extends Thread{public void run(){for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+i);try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}}}}public class Thread1 {public static void main(String[]args){A aa=new A();aa.start();}}
Thread的join方法:如a.join();暂停当前正在执行的线程,直到a的线程运行终止之后当前线程才有机会得到执行,注意:不是暂停a对象的线程,而是当前运行的线程
class A extends Thread{public void run(){for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+i);}}}public class Thread1 {public static void main(String[]args){A aa=new A();aa.start();try{aa.join();}catch(Exception e){e.printStackTrace();}for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+i);}}}Thread的优先级:
getPriority:获取优先级
setPriority:设置优先级
Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。
线程调度器用数字表现,范围从一到十,一个线程默认是5。
通常优先级高的比优先级低的要先执行,但并不是一定的!因为实际开发中并不单纯依赖优先级来决定优先级的运行顺序
class A implements Runnable{ public void run() { for(int i=0;i<10;i++) { System.out.println("A"+i); } }}class B implements Runnable{ public void run() { for(int i=0;i<10;i++) { System.out.println("B"+i); } }}public class Thread3 { public static void main(String[]args) { Thread t1=new Thread(new A()); Thread t2=new Thread(new B()); t1.setPriority(Thread.MIN_PRIORITY); t2.setPriority(Thread.MAX_PRIORITY); t1.start(); t2.start(); }}
优先级越高!越容易被CPU先调用!
线程的同步
卖票系统!
假如有三个地方,A,B,C同时卖票
假如代码写成这样
if(票数大于0){买票票数-1}
当A发现票大于0的时候,本应该执行下一步,假如此时CPU切换的B线程的时候,发现票数大于0(因为在A线程里面,票数没有减一),当在B中发现票数大于0之后,假如CPU又切换到C线程里面,发现票数还是大于0(同理)假如票只有一张,那么此时就相当于一张票被卖了三次。
这将产生错误!
class A implements Runnable{private int tickets=100;public void run(){while(true){if(tickets>0){System.out.println(Thread.currentThread().getName()+"正在卖出第"+tickets+"张票");tickets--;}else{break;}}}}public class Thread4 {public static void main(String[]args){A a=new A();Thread t1=new Thread(a);t1.start();A b=new A();Thread t2=new Thread(b);t2.start();}}
以上代码运行结果:
每张票都被卖出去两次!!!这是不合理的
导致这个的原因是a对象和b对象都有一个属于自己的tickets 100
那么接下来看以下程序
class A implements Runnable{static int tickets=100;public void run(){while(true){if(tickets>0){System.out.println(Thread.currentThread().getName()+"正在卖出第"+tickets+"张票");tickets--;}else{break;}}}}public class Thread4 {public static void main(String[]args){A a=new A();Thread t1=new Thread(a);t1.start();A b=new A();Thread t2=new Thread(b);t2.start();}}
把票数改成静态的
结果是这样的:
那么来分析一下这个结果是为什么,当Thread-0发现票数是100的时候执行卖出操作,然后立刻切换的线程1然后发现还是100但是没有执行卖出操作又转换为线程0,此时减一然后就变成99、98、97、96、95、这个时候立刻切换成线程1执行卖出操作,打印出来,。
简单来说:CPU会在线程之间来回切换!
好的,重点来了!
Synchronized---同步
class A implements Runnable{static int tickets=100;public void run(){while(true){synchronized(this){if(tickets>0){System.out.println(Thread.currentThread().getName()+"正在卖出第"+tickets+"张票");tickets--;}else{break;}}}}}public class Thread4 {public static void main(String[]args){A a=new A();Thread t1=new Thread(a);Thread t2=new Thread(a);t1.start();t2.start();}}结果如下
synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、 D等)正在用这个方法(或者该类的其他同步方法),有的话要等正在使用synchronized方法的线程B(或者C 、D)运行完这个方法后再运行此线程A,没有的话,锁定调用者,然后直接运行。它包括两种用法:synchronized 方法和 synchronized 块。
- Java线程:什么是线程
- Java线程:线程池
- java线程--线程退出
- JAVA-线程/线程锁
- Java线程:什么是线程
- Java线程:线程中断
- Java线程:线程状态
- Java线程: 线程调度
- Java线程:线程交互
- java--线程--线程池
- java 线程
- Java线程
- java线程
- java线程
- Java线程
- Java线程
- java线程
- JAVA 线程
- vs2015 c# Interactive
- Python 文档阅读01
- 数据结构 综合
- 你好
- Java集合框架面试
- JAVA---线程
- 【Android自定义View】仿Photoshop取色器ColorPicker(四)完结篇
- JAVA获取服务器路径的方法
- 使用Glide的一个优化
- ZooKeeper server连接状态
- 《HTML5权威指南》之使用边框和背景
- protobuf lua 版注意点
- 【机器学习-西瓜书】三、线性回归;对数线性回归
- 横向菜单和xlistview