java线程基础知识和小案例
来源:互联网 发布:网站数据库对接 编辑:程序博客网 时间:2024/04/28 20:55
线程、进程概念:
进程
线程定义和线程实例化(两种方式)
新状态:线程对象已经创建,但还没有调用start()方法
synchronized关键字
进程
在Java语言中,当用Java命令执行.class文件或执行.exe文件,会首先将程序代码Load到内存区,然后由操作系统找到程序代码的入口(main方法)开始执行程序。以上是关于Java程序执行过程的内存分析的内容。当把程序代码Load到内存区时,已经算是一个进程了,这时它并没有执行,这里强调进程是个静态的概念。我个人认为,如果强调它是个静态的概念,就把进程和线程割裂开来说了。把进程解释为内存中运行的应用程序也未为不可。尽管我们常说的进程开始执行了,实质上是程序中的主线程开始执行了。
线程:
是一个程序中不同的执行路径。
是一个程序中不同的执行路径。
多进程:
同时在内存中运行多个应用程序。
同时在内存中运行多个应用程序。
多线程:
对于单个CPU,实质上是不存在多线程的。CPU只能轮换处理多个线程,在某一时刻,只能处理一个线程,但是因为处理的速度极快,人根本感觉不到它轮换处理线程的时间差,所以给人的感觉是“同时”在执行多个线程,这也就是分时复用。对于多个CPU,才会存在多线程。
对于单个CPU,实质上是不存在多线程的。CPU只能轮换处理多个线程,在某一时刻,只能处理一个线程,但是因为处理的速度极快,人根本感觉不到它轮换处理线程的时间差,所以给人的感觉是“同时”在执行多个线程,这也就是分时复用。对于多个CPU,才会存在多线程。
线程创建和启动:
线程定义和线程实例化(两种方式)
1.子类继承Thread,重写Run方法------>new 子类()
2.实现Runnable接口------>调用Thread构造方法new Thread(Runnable target)
线程启动
调用Thread对象的Start方法
案例:
public class Test1 {public static void main(String[] args){//这是一个非常好的操作//启动新线程,来完成输出事件的操作MyTime mt=new MyTime();//启动线程,Thread类的start()mt.start();for(int i=0;i<100;i++){try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("主线程:"+i);}}}
class MyTime extends Thread{//放入线程要执行的代码,非常好时public void run(){boolean flag=true;while(flag){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}Date d=new Date();System.out.println(d);}}}
线程状态转换:
新状态:线程对象已经创建,但还没有调用start()方法
就绪状态:调用start()方法,但调度程序还没有把它选定为运行的线程(即还没有调用Run方法)
运行状态:被选定为当前执行的线程,执行Run方法
阻塞/等待/睡眠状态:某种事件发生,线程进入阻塞状态,带阻塞解除,重新回到就绪状态,等待调度。
死亡态:线程的Run方法完成时,就认为它死去。
:
线程控制方法:
1.睡眠
Thread.sleep()
使当前正在执行的线程暂停执行,开始睡眠,睡眠指定时长后,自动苏醒,进入就绪状态,而不是运行状态。
2.设置线程优先级
setPriority()
3.线程让步
Yield()理论上是让具有相同优先级的线程具有运行的机会,本身由当前执行的线程从运行状态回到就绪状态,但是可能会被再次选中,并不能保证真正的让步。
案例:
/** yield与sleep的区别* sleep给与其它线程运行的机会,但不考虑其它线程的优先级,但yield只会让位给相同或更高优先级的线程* sleep有异常,yield没有*/public class Test12 {public static void main(String[] args) {YieldOne y1=new YieldOne();YieldOne y2=new YieldOne();Thread t1=new Thread(y1,"a");Thread t2=new Thread(y2,"b");t1.setPriority(5);t1.start();t2.setPriority(10);//第二个线程的优先级高t2.start();}}class YieldOne implements Runnable{public void run() {if("a".equals(Thread.currentThread().getName())){Thread.yield();//yield只会执行权放给优先级高的线程}for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+": "+i);}}}
4.线程合并
在一个A线程中如果加入B线程.Join,则A线程会等B线程执行完,才执行。
案例:
//使用join来控制线程运行
public class Test11 {public static void main(String[] args) throws InterruptedException {LifeCircle lc=new LifeCircle();System.out.println(lc.isAlive());lc.start();System.out.println(lc.isAlive());lc.join();//则表示主线程阻塞,让lc运行完System.out.println("主程序");System.out.println(lc.isAlive());}}class LifeCircle extends Thread{public void run(){int i=0;while((++i)<10){System.out.println(Thread.currentThread().getName()+":"+i);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}}
线程同步和锁机制:
synchronized关键字
Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。
当两个并发 线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行 该代码块。
然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块。
当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
Wait释放当前线程在该对象上所获得的锁
当一个线程获得了对象的锁之后,即使该线程在Sleep,也不会释放这个锁。
案例:
public class Test13 {public static void main(String[] args) {SellTickOp sto=new SellTickOp(10);Thread counter1=new Thread(sto,"Ann");Thread counter2=new Thread(sto,"Bob");Thread counter3=new Thread(sto,"Mei");counter1.start();counter2.start();counter3.start();}}class SellTickOp implements Runnable{int tickets;Random r=new Random();public SellTickOp(int tickets){this.tickets=tickets;}public void run() {while(true){synchronized(this){//每次只允许一个人过if(tickets>0){//转控制权try {Thread.sleep(r.nextInt(400));System.out.println(Thread.currentThread().getName()+"在sell第"+(tickets--)+"张票");} catch (InterruptedException e) {e.printStackTrace();}}else{return;}}}}}
0 0
- java线程基础知识和小案例
- java线程和小案例
- 线程wait小案例
- 线程Notify小案例
- Java中的线程池(1)----线程池基础知识和CachedThreadPool
- Qt线程同步小案例
- java线程概念案例
- java线程概念案例
- java io小案例
- JAVA反射小案例
- 一些java小案例
- java基础知识(线程方面)
- java线程安全-基础知识
- java 线程基础知识
- java线程基础知识
- java线程基础知识总结
- java线程基础知识
- Java线程基础知识
- logback logback.xml 常用配置详解
- 【日常学习】【数学】【矩阵乘法】【大数乘方取模】codevs1982 加密算法题解
- bzoj1617【Usaco2008 Mar】River Crossing 渡河问题
- 计步准确,算法智能——体验连爱智能手环
- 客户端和服务端交互的三种方式
- java线程基础知识和小案例
- Dev C++报告窗口不能自动弹出
- SDWebImage源码解析之SDWebImageManager的注解
- 布局的重复使用
- bzoj1618【Usaco2008 Nov】Buying Hay 购买干草
- svn 命令行下常用的几个命令
- 黑马程序员——OC类的初始化与点语法
- Android依赖注入类库 Butter Knife的使用
- 线程:sleep()、wait()、yield()和join()方法