
Java语言入门(九)——线程类及多线程
发布日期:2022-02-28 07:22:50
浏览次数:16
分类:技术文章
本文共 9518 字,大约阅读时间需要 31 分钟。
Java语言入门
线程与进程
1 进程是指运行中的应用程序,每一个进程都有自己独立的内存空间。对一个应用程序可以同时启动多个进程。
2 线程是指进程中的一个执行流程,有时也称为执行情景。一个进程可以由多个线程组成,即在一个进程中可以同时运行多个不同的线程,它们分别执行不同的任务。当进程内的多个线程同时运行,这种运行方式称为并发运行。 3 进程消失了,线程还存在么?答:不在 4 线程消失了,进程还会存在么?答:可能在 5 线程依附进程 比进程小,不同进程的线程不可比较大小 JVM 对于一个java系统,至少要启动两个线程main gcjava.lang.Thread public static Thread currentThread()public final String getName()class Test{ public static void main(String args[]) { System.out.println(Thread.currentThread().getName()); }}
线程的创建和启动方法
1 定义一个Thread类的子类,覆盖Thread类的run()方法,然后创建该子类的实例。
2 定义一个实现Runnable接口的类,实现它的run()方法,然后将这个类的实例作为Thread的构造方法的参数,创建Thread类的实例。 3 两种创建线程的方法是有区别的,对于共享资源来说,最好用实现runnable接口的方法class TT extends Thread//线程的第一种创建方法{ public void run() { for(int i=0;i<10;i++) System.out.println(Thread.currentThread().getName());}}class Test-9.1{ public static void main(String[] args) { TT t1=new TT(); t1.run(); System.out.println(Thread.currentThread().getName()+";");}}//输出11个main
class TT extends Thread{ public void run() { for(int i=0;i<10;i++) System.out.println(Thread.currentThread().getName()); }}class Test-9.2{ public static void main(String[] args) { TT t1=new TT(); //t1.run(); t1.start();//线程的启动 System.out.println(Thread.currentThread().getName()+";");}}//输出main;和10个Thread-0
class TT extends Thread{ public void run() { for(int i=0;i<10;i++) System.out.println(Thread.currentThread().getName()); }}class Test-9.3{ public static void main(String[] args) { TT t1=new TT(); TT t2=new TT(); TT t3=new TT(); t1.setName("huang"); t1.start(); t2.start(); t3.start();System.out.println(Thread.currentThread().getName()+";");}}
class TT implements Runnable//线程的第二种创建方法{ public void run() { for(int i=0;i<10;i++) System.out.println(Thread.currentThread().getName());}}class Test-9.4{ public static void main(String[] args) { Runnable t=new TT(); Thread t1=new Thread(t); t1.start(); System.out.println(Thread.currentThread().getName()+";");}}//输出main;和10个Thread-0
class TT extends Thread//实现售票{ /*static*/ int tickets=20; public void run() { //int tickets=20;错误 for (int i=0;i<40;i++) { if (tickets>0) { System.out.println(Thread.currentThread().getName()+";"+tickets--); }}} }class Test-9.5{ public static void main(String args[]) { TT t1=new TT(); t1.setName("1"); TT t2=new TT(); t2.setName("2"); TT t3=new TT(); t3.setName("3"); t1.start(); t2.start(); t3.start(); System.out.println(Thread.currentThread().getName()+"*****");} }
class TT implements Runnable//实现售票{ /*static*/ int tickets=20; public void run() { //int tickets=20;错误 for (int i=0;i<40;i++) { if (tickets>0) { System.out.println(Thread.currentThread().getName()+";"+tickets--); }}} }class Test-9.6{ public static void main(String args[]) { TT t1=new TT(); /*TT t2=new TT();TT t3=new TT();*/ new Thread(t1,"1").start(); new Thread(t1,"2").start(); new Thread(t1,"3").start(); System.out.println(Thread.currentThread().getName()+"*****");} }
class TT implements Runnable{ static int tickets=20; public void run()/*throws Exception 错误*/ { for(int i=0;i<40;i++) { if(tickets>0) { try { Thread.sleep(500);}//只是让线程执行速度减缓,不影响代码执行本身 catch(Exception e){ } System.out.println(Thread.currentThread().getName()+":"+tickets--);}} }}class Test-9.7{ public static void main(String[] args) throws Exception { TT t1=new TT(); TT t2=new TT(); TT t3=new TT(); new Thread(t1,"1站").start(); new Thread(t2,"2站").start(); new Thread(t3,"3站").start();}//出现错误有:重复、0、-1//线程的安全性问题(同步)
线程同步synchronized(同步代码块、同步方法)以及锁旗标
class TT implements Runnable{ static int tickets=20; String name="huang"; public void run() { for(int i=0;i<40;i++) { synchronized(name) //同步代码块 //synchronized(this) { if(tickets>0) { try { Thread.sleep(500);}//只是让线程执行速度减缓,不影响代码执行本身 catch(Exception e){ } System.out.println(Thread.currentThread().getName()+":"+tickets--);}} }}class Test-9.8{ public static void main(String[] args) throws Exception { TT t1=new TT(); TT t2=new TT(); TT t3=new TT(); new Thread(t1,"1站").start(); new Thread(t2,"2站").start(); new Thread(t3,"3站").start();} //synchronized(公认对象名[锁旗标])/*添加同步代码块对象,必须是公认的。不能在run方法里,若在run方法则无效*/
售票实例讲解
public class ProducerAndConsumer { /** * 假定开始售票处并没有票,一个线程往里存票,另一个线程则往外卖票。 * 新建一个票类对象,让存票和售票线程都访问它。 * 两个线程共享同一个数据对象来实现对同一份数据的操作 */ public static void main(String[] args) { Tickets t=new Tickets(10); //新建一个票类对象,总票数作为参数 new Producer(t).start(); //以票类对象为参数创建存票线程对象,并启动 new Consumer(t).start();//以同一个票类对象为参数创建售票线程,并启动 } } //票类 class Tickets{ int number=0; //票号 int size; //总票数 boolean available=false; //表示目前是否有票可售 public Tickets(int size){ this.size=size;}//构造函数,传入总票数参数 } //存票线程 class Producer extends Thread{ Tickets t=null; public Producer(Tickets t) { this.t=t; }//构造函数:以一个票类为参数 public void run() { while(t.numbersize表示售票结束 } }
Thread类的方法
1 currentThread() 返回当前运行的Thread对象。
2 start() 启动一个线程。 3 run() 线程体,由start()方法调用,当run()方法返回时,当前的线程结束。 4 stop() 使调用它的线程立即停止执行。 5 sleep(int n)使线程睡眠n毫秒,n毫秒后,线程可以再次运行。 6 suspend() 使线程挂起,暂停运行。 7 resume() 恢复挂起的线程,使其处于可运行状态(Runnable)。 8 yield() 将CPU控制权主动移交到下一个可运行线程。 9 setPriority() 设置线程优先级。 getPriority() 返回线程优先级。 10 setName() 设置线程的名字。 getName() 返回该线程的名字。 11 isAlive( ) 如果线程已被启动并且未被终止,那么isAlive( )返回true。如果返回false,则该线程是新创建或是已被终止的。死锁
1 死锁是程序运行时发生的一种状态
2 产生原因:多个线程共享同一资源时,要进行加锁操作(同步),但是,过多的同步会造成死锁 3 当一个线程等待由另一个线程持有的锁,而后者正在等待已被第一个线程持有的锁时,就会发生死锁。Java不监测也不试图避免这种情况。因而保证不发生死锁就成了程序员的责任class ST implements Runnable //死锁程序的模拟:{ int ticket=10; String str=new String("hh");/*添加同步代码块对象,必须是公认的。不能在run方法里,若在run方法则无效*/ public void run() { if(str.equals("huang")) { for (int i=0;i<30 ;i++ ) { this.sale(); } else { for (int i=0;i<30 ;i++ ) { synchronized(str) //str称为锁旗标或监视器,有0,1状态,进去后为0,出来后为1 { if (ticket>0) { try{ Thread.sleep(100); } catch (Exception e){ } synchronized(this) { } System.out.println(Thread.currentThread().getName()+" :"+ticket--);/*ticket>0和ticket--不是原子性操作时,解决方法:(1)代码写进同步代码,synchronized()速度慢,因为synchronized()每次检查状态*/}}} }}public synchronized void sale() //改为public void sale()不同步,同步方法的锁旗标为this //买票的方法,加上synchronized,该方法就同步{ if (ticket>0) { try { Thread.sleep(100);} catch (Exception e){ } synchronized(str){ } System.out.println("i am here"); System.out.println(Thread.currentThread().getName()+" :"+ticket--);}}}class Test-9.10{ public static void main(String[] args) { ST s=new ST(); Thread t=new Thread(s,"station1"); Thread t1=new Thread(s,"station2"); t.start(); try{ Thread.sleep(100);} catch(Exception e){ } s .str="huang"; t1.start(); } }
对象数组
class Person //对象数组{ String name; int age; int ID; public void say() { System.out.println(name+";"+age); }}class Test-9.11{ public static void main(String[] args) { Person[] p=new Person[10];//生成10个对象 //对象数组。每个单元存放的都是一个对象 Person s=new Person(); p[0]=s; p[0].name="zhangsan"; p[0].ID=1;p[0].say();}
内存图讲解
1 程序中用关键字new出来的东西都是存放在heap segment。
2 程序中的局部变量存放在stack segment,这些局部变量是在具体方法执行结束之后,系统自动释放内存资源(而heap segment中的资源需要java垃圾回收机制来处理)。形参一定在栈stack内存里 3 程序中的方法,是内存中的code segment中的,而且是多个对象 共享一个代码空间区域。 4 static静态变量,需要放在内存中的data segment生产者与消费者实例讲解
//生产者与消费者问题//涉及线程的通信class SZP //山楂片{ private int ID; public SZP(int ID) { this.ID=ID;} public String toString() { return "SZP"+ID;}}class RQ //容器{ int top=0; SZP [] sz = new SZP[10]; public synchronized void push(SZP s) { if(top==sz.length) { try{ this.wait(); } //wait时,锁给别人,才自动释放;sleep睡觉时,锁还在。 catch (Exception e){ } } this.notify(); //notify()唤醒,唤醒的是别人,不是自己 sz[top]=s; top++; } public synchronized SZP pop() { if(top==0) { try{ this.wait();} catch (Exception e){ } } this.notify(); top--; return sz[top]; }}class Producer implements Runnable //生产者{ RQ r=null; public Producer(RQ r) { this.r=r;} public void run() { for(int i=0;i<30;i++) { SZP s=new SZP(i); r.push(s); try{ Thread.sleep(10);} catch (Exception e){ } System.out.println("produce: "+s); } }}class Consumer implements Runnable //消费者{ RQ r=null; public Consumer(RQ r) { this.r=r;} public void run() { for(int i=0;i<30;i++) { SZP s=r.pop(); try{ Thread.sleep(1000);} catch (Exception e){ } System.out.println("consumer: "+s); } }}class Test-9.12{ public static void main(String [] args) { RQ r=new RQ(); Producer p=new Producer(r); Consumer c=new Consumer(r); new Thread(p).start(); new Thread(c).start(); }}
转载地址:https://blog.csdn.net/weixin_45854582/article/details/106151329 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2023年08月28日 02时39分09秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
关于测试
2019-03-07
HTML5
2019-03-07
节点List相关操作
2019-03-07
命名空间
2019-03-07
读书笔记
2019-03-07
Unity中常用Time类详解
2019-03-07
Echoworx为电子邮件加密平台增加生物特征身份验证功能
2019-03-07
法拉第未来选择Velodyne作为旗舰超豪华电动车FF 91的独家激光雷达供应商
2019-03-07
获高瓴资本5.3亿美元融资,京东健康就能“高枕无忧”了?
2019-03-07
被“铲屎官”养成的千亿新战场,宠物经济风口机会在哪里?
2019-03-07
奢侈品电商,压死趣店的最后一根稻草?
2019-03-07
在外卖平台也能当主播,美团直播到底“行不行”?
2019-03-07
收购快钱做线下支付,京东数科与蚂蚁终有一战?
2019-03-07
网红经济当道,奶茶店成功路能否“复制”?
2019-03-07
嘀嗒出行IPO 会成为出行界的“拼多多”吗
2019-03-07
靠手表“上位”的儿童社交,“红眼”微信做儿童版就有机会了吗?
2019-03-07
阿里新晋图腾犀牛,真能所向披靡吗?
2019-03-07
内测“轻雀协作”,三入办公市场的快手还有机会吗?
2019-03-07
海底捞面馆是谁的拦路虎,又是谁的敲门砖?
2019-03-07
“老铁支付”在路上,快手支付能为快手电商保驾护航吗
2019-03-07