java多线程编程详细入门教程

java多线程编程详细入门教程1 概念 amp amp nbsp amp amp nbsp amp amp nbsp amp amp nbsp amp amp nbsp 线程是 jvm 调度的最小单元 也叫做轻量级进程 进程是由线程组成 线程拥有私有的程序技术器以及栈 并且能够访问堆中的共享资源 这里提出一个问题 为什么要用多线程 有一下几点 首先 随着 cpu 核心数的增加 计算机硬件的并行计算能力得到提升

class MyThread extends Thread{ int j=20; public void run(){ for (int i = 0; i < 20; i++) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(this.getName()+",i="+j--); } } } 

然后main函数中创建:

class MyThread extends Thread{ int j=20; public void run(){ for (int i = 0; i < 20; i++) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(this.getName()+",i="+j--); } } } 

第二种方法:

class MyRunnable implements Runnable{ int j=20; @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println(Thread.currentThread().getName()+",j="+this.j--); } } } 

main函数中:

 MyRunnable myRunnable = new MyRunnable(); Thread t1 = new Thread(myRunnable); Thread t2 = new Thread(myRunnable); t1.start(); t2.start(); 
class MyRunnable implements Runnable{ static int j=10000; @Override public void run() { for (int i = 0; i < 5000; i++) { System.out.println(j--); } } } 

main函数中:

 MyRunnable myRunnable = new MyRunnable(); Thread t1 = new Thread(myRunnable); Thread t2 = new Thread(myRunnable); t1.start(); t2.start(); 

可以看到,这里同时两个线程同时对共享变量j进行访问,并且减1,但最后的输出结果却是:

48 47 46 
class MyRunnable implements Runnable{ static int j=10000; @Override public synchronized void run() { for (int i = 0; i < 5000; i++) { System.out.println(j--); } } } 

main中创建两个线程,测试多次的结果都是:

3 2 1 
 try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } 
class MyThreadd extends Thread{ public MyThreadd(String name) { // TODO Auto-generated constructor stub super(name); } public void run(){ synchronized (this) { System.out.println(Thread.currentThread().getName()+" notify a thread"); notify(); } while(true); } 

main中:

 MyThreadd t1 = new MyThreadd("t1"); synchronized (t1) { System.out.println(Thread.currentThread().getName()+" start t1"); t1.start(); System.out.println(Thread.currentThread().getName()+" wait"); t1.wait(); System.out.println(Thread.currentThread().getName()+" waked up"); } 
class MyRuu extends Thread{ public MyRuu(String name) { super(name); } public void run() { System.out.println(Thread.currentThread().getName()); //while(true); } } 

main函数中:

 MyRuu myRuu = new MyRuu("t1"); System.out.println(Thread.currentThread().getName()+" start t1"); myRuu.start(); System.out.println(Thread.currentThread().getName() +" join"); myRuu.join(); System.out.println(Thread.currentThread().getName() +" waked up"); 

运行结果:

main start t1 main join t1 main waked up 
class MyRun extends Thread{ Object obj; public MyRun(String name,Object obj) { // TODO Auto-generated constructor stub super(name); this.obj = obj; } public void run(){ // synchronized (obj) { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+ " i="+i); if(i%2 == 0) Thread.yield(); } // } } } 

main函数中:

 Object obj = new Object(); // TODO Auto-generated method stub MyRun t1 = new MyRun("t1",obj); MyRun t2 = new MyRun("t2",obj); t1.start(); t2.start(); 

结果:

t1 i=0 t2 i=0 t1 i=1 t2 i=1 t2 i=2 t1 i=2 t2 i=3 t2 i=4 t1 i=3 t1 i=4 t2 i=5 t2 i=6 t1 i=5 t1 i=6 t2 i=7 t2 i=8 t1 i=7 t1 i=8 t2 i=9 t1 i=9 
class RunInt extends Thread{ public void run() { while(!this.isInterrupted()){ synchronized (this) { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+" i="+i); } try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block System.out.println(Thread.currentThread().getName()+" interrupted!"); break; } } } System.out.println(Thread.currentThread().getName()+" dead"); } } 

main中:

 RunInt r1 = new RunInt(); r1.start(); Thread.yield(); synchronized (r1) { System.out.println(Thread.currentThread().getName()+" intertupt r1"); r1.interrupt(); } 

结果

main intertupt r1 Thread-0 i=0 Thread-0 i=1 Thread-0 i=2 Thread-0 i=3 Thread-0 i=4 Thread-0 i=5 Thread-0 i=6 Thread-0 i=7 Thread-0 i=8 Thread-0 i=9 Thread-0 interrupted! Thread-0 dead 
 Thread t1 = new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub synchronized (A) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (B) { System.out.println("haha"); } } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub synchronized (B) { synchronized (A) { System.out.println("xixi"); } } } }); t1.start(); t2.start(); 
class Depot{ private int capacity; private int size=0; public Depot(int c) { // TODO Auto-generated constructor stub this.capacity = c; } public synchronized void product(int count) throws InterruptedException{ while(count>0){ if(size >= capacity) wait(); //真实生产数量 int realcount = (capacity-size)>=count?count:(capacity-size); System.out.print(Thread.currentThread().getName()+"--本次想要生产:"+count+",本次实际生产:"+realcount); //下次生产数量 count = count - realcount; //仓库剩余 size += realcount; System.out.println(",下次想要生产:"+count+",仓库真实容量:"+size); notifyAll(); } } public synchronized void comsume(int count) throws InterruptedException { while(count>0){ if(size <= 0) wait(); //真实消费数量 int realcount = (size>=count)?count:size; System.out.print(Thread.currentThread().getName()+"--本次想要消费:"+count+",本次真实消费:"+realcount); //下次消费数量 count = count - realcount; //仓库剩余 size -= realcount; System.out.println("下次想要消费:"+count+",仓库剩余:"+size); notify(); } } } 

生产者代码:

class Producer { Depot depot; public Producer(Depot depot) { // TODO Auto-generated constructor stub this.depot = depot; } public void produce(final int count) { new Thread(){ public void run() { try { depot.product(count); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }.start(); } } 

消费者代码:

class Consumer{ Depot depot; public Consumer(Depot depot) { // TODO Auto-generated constructor stub this.depot = depot; } public void consume(final int count) { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { depot.comsume(count); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } } 

main中:

 Depot depot = new Depot(100); Producer producer = new Producer(depot); Consumer consumer = new Consumer(depot); producer.produce(60); producer.produce(50); producer.produce(30); consumer.consume(50); consumer.consume(110); producer.produce(40); 

结果:

Thread-0--本次想要生产:60,本次实际生产:60,下次想要生产:0,仓库真实容量:60 Thread-1--本次想要生产:50,本次实际生产:40,下次想要生产:10,仓库真实容量:100 Thread-4--本次想要消费:110,本次真实消费:100下次想要消费:10,仓库剩余:0 Thread-1--本次想要生产:10,本次实际生产:10,下次想要生产:0,仓库真实容量:10 Thread-4--本次想要消费:10,本次真实消费:10下次想要消费:0,仓库剩余:0 Thread-5--本次想要生产:40,本次实际生产:40,下次想要生产:0,仓库真实容量:40 Thread-2--本次想要生产:30,本次实际生产:30,下次想要生产:0,仓库真实容量:70 Thread-3--本次想要消费:50,本次真实消费:50下次想要消费:0,仓库剩余:20 
class Pro1{ private BlockingQueue 
  
    blockingQueue1; public Pro1(BlockingQueue 
   
     blockingQueue) { // TODO Auto-generated constructor stub this.blockingQueue1 = blockingQueue; } public void produce(final int count) { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < count; i++) { try { Thread.sleep(100); blockingQueue1.put(100); System.out.println("生产者,仓库剩余容量"+blockingQueue1.size()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }).start(); } } 
    
  

消费者:

class Con1{ private BlockingQueue 
  
    blockingQueue; public Con1(BlockingQueue 
   
     blockingQueue) { // TODO Auto-generated constructor stub this.blockingQueue = blockingQueue; } public void consume(final int count) { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < count; i++) { try { Thread.sleep(100); blockingQueue.take(); System.out.println("消费者,本次仓库剩余:"+blockingQueue.size()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }).start(); } } 
    
  

main函数:

 BlockingQueue 
  
    blockingQueue = new ArrayBlockingQueue 
   
     (5); Pro1 pro1 = new Pro1(blockingQueue); Con1 con1 = new Con1(blockingQueue); pro1.produce(10); con1.consume(7); 
    
  

结果:

消费者,本次仓库剩余:0 生产者,仓库剩余容量0 生产者,仓库剩余容量1 消费者,本次仓库剩余:0 生产者,仓库剩余容量1 消费者,本次仓库剩余:0 生产者,仓库剩余容量0 消费者,本次仓库剩余:0 生产者,仓库剩余容量1 消费者,本次仓库剩余:0 生产者,仓库剩余容量1 消费者,本次仓库剩余:0 生产者,仓库剩余容量1 消费者,本次仓库剩余:0 生产者,仓库剩余容量1 生产者,仓库剩余容量2 生产者,仓库剩余容量3 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/218387.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午7:23
下一篇 2026年3月18日 上午7:23


相关推荐

  • android 屏幕触摸事件及处理机制解读

    android 屏幕触摸事件及处理机制解读原创性声明:Android最让我开心和有成就感的就是可以实现自定义,追根朔源是开源带来的,出于普适性,google不会提供定制性特别强的视图组件,但是我们可以自己动手,丰衣足食。但是,往往自定义的时候会出现好多问题,说到底是还没有吃透,我不推荐学生时期自学的时候过分追究原理,那个时期并不合适做这件事,那种闭关到世界第一再出关的苦学我也是不认可的。学习就是要循序渐进,慢慢吃透,扩展出

    2025年10月24日
    3
  • 2022年G3锅炉水处理找解析及G3锅炉水处理考试试卷[通俗易懂]

    题库来源:安全生产模拟考试一点通公众号小程序安全生产模拟考试一点通:G3锅炉水处理找解析是安全生产模拟考试一点通生成的,G3锅炉水处理证模拟考试题库是根据G3锅炉水处理最新版教材汇编出G3锅炉水处理仿真模拟考试。2022年G3锅炉水处理找解析及G3锅炉水处理考试试卷1、【多选题】水垢对锅炉的危害主要有浪费燃料()。(ABD)A、.损坏锅炉受热面B、.降低锅炉出力C、.减少供汽时间D、.缩短锅炉使用寿命E、.提高了环境温度2、【多选题】特种设备作业人员应当遵守()规…

    2022年4月14日
    49
  • asp.net mvc 下拉框级联

    asp.net mvc 下拉框级联给自己需要级联的控制器添加要级联的下拉框获取#region//获取宿舍楼[HttpPost]publicActionResultDrom(stringid){objectobj=getDrom(id);returnJson(obj);}//获取宿舍楼publicList<SelectList.

    2022年7月22日
    15
  • SpringBoot 中常用注解@Controller/@RestController/@RequestMapping介绍

    SpringBoot 中常用注解@Controller/@RestController/@RequestMapping介绍SpringBoot 中常用注解 Controller RestControll RequestMappi 介绍 Controller 处理 http 请求 Controller ResponseBody RequestMappi value hello method RequestMetho GET

    2026年3月19日
    1
  • Telerik的RadControls控件(四)

    Telerik的RadControls控件(四)朋友们、同行们通过前面《跟我学Telerik公司的RadControls控件》系列三篇的学习,你一定会内心有一种涌动,有种相见(RadControls)恨晚的感觉。那就一起加入学习RadControls控件的行列,为IT的朋友提供更加明了化的技术大餐,欢迎……  今天我将和你分享另一个更加完美的技术控件(TelerikRadTreeview)控件:  RadTreeview 是一个功

    2022年7月24日
    8
  • linux p2v步骤,P2V操作完整步骤,物理机转换openstack虚拟机

    linux p2v步骤,P2V操作完整步骤,物理机转换openstack虚拟机注意:P2V之前系统盘要给足够,迁移会出现根目录空间不足情况。本次实验根目录有800G,virshpool池用的是/var/lib/glance的空间1.8T。迁移中出现问题,参考本博客《P2V问题汇总》文章。1、文件上传virtio和p2v安装包上传更新YUM源,参考本博客里面《Centos更新源.docx》再安装:yum-yinstallqemu-kvmlibvirtpyth…

    2022年7月26日
    15

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号