线程并发之回顾传统线程创建,定时器及线程间的通讯

本文介绍了Java中创建线程的传统方法,包括通过继承Thread类和实现Runnable接口的方式,并探讨了线程间的互斥与通讯机制,同时展示了如何利用synchronized关键字实现同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建线程的两种传统方式
在Thread子类覆盖的run方法中编写运行代码
在传递给Thread对象的Runnable对象的run方法中编写代码
 
  
package cn.itcast.thread;

public class TraditionalThreadSynchronized {

 /**
  * @param args
  */
 public static void main(String[] args) {
  new TraditionalThreadSynchronized().init();
 }
 
 public void init(){
  final Outputer outputer = new Outputer();
    new Thread(new Runnable(){
             
   @Override
   public void run() {
    
    while(true){
               try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    outputer.output("zhangxiaoxiang");
    }
   }
     
     
    }).start();
    
    new Thread(new Runnable(){
            
   @Override
   public void run() {
    while(true){
               try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    outputer.output("lihuoming");
    }
   }
     
     
    }).start();
 }
 private static class Outputer {
  //必须保证用同一个监视器对象,才能起到互斥作用
  public void output(String name){
   synchronized(Outputer.this){
    int len = name.length();
    for(int i = 0;i<len;i++){
     System.out.print(name.charAt(i));
    }
    System.out.println();
   }
   
  }
  public synchronized void output2(String name){
  
    int len = name.length();
    for(int i = 0;i<len;i++){
     System.out.print(name.charAt(i));
    }
    System.out.println();
   
   
  }
  public static synchronized void output3(String name){
   
    int len = name.length();
    for(int i = 0;i<len;i++){
     System.out.print(name.charAt(i));
    }
    System.out.println();
   
   
  }
 }
}


 
  
 
  
 
 
new Thread(
new Runnable(){
public void run(){
System.out.println("run method of runnable!");
} 
}
){
public void run(){
System.out.println("run method of thread!");
}
}.start();   
              

总结:查看Thread类的run()方法的源代码,可以看到其实这两种方式都是在调用Thread对象的run方法,如果Thread类的run方法没有被覆盖,并且为该Thread对象设置了一个Runnable对象,该run方法会调用Runnable对象的run方法。
•涉及到的一个以往知识点:匿名内部类对象的构造方法如何调用父类的非默认构造方法。
实际应用:第二种,为什么?
第二种方式将代码封装到了一个对象中,更加符合 java面向对象编程的思想
多线程机制会提高程序的运行效率么?不会.运行效率可能会更低 线程切换之间会消耗资源.
为什么有多线程下载? 实际上是抢了服务器的带宽.计算机本身并没有变快,而是让服务器提供了更多的服务.
定时器的应用:
Timer类
TimerTask类
可以借助quartz控制具体的实现:
Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB作业预构建,JavaMail及其它,支持cron-like表达式等等。

你曾经需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后一天执行。一个自动执行而无须干预的任务在执行过程中如果发生一个严重错误,应用能够知到其执行失败并尝试重新执行吗?你和你的团队是用Java编程吗?如果这些问题中任何一个你回答是,那么你应该使用Quartz调度器。

旁注:Matrix目前就大量使用到了Quartz。比如,排名统计功能的实现,在Jmatrix里通过Quartz定义了一个定时调度作业,在每天凌晨一点,作业开始工作,重新统计大家的Karma和排名等。

还有,RSS文件的生成,也是通过Quartz定义作业,每隔半个小时生成一次RSS XML文件。

线程之间的互斥与通讯:

1. 互斥: 用synchronized(object){ } 代码块(需要保证object是一个)或者在方法上加synchronized关键字

package cn.itcast.thread;

public class TraditionalThreadSynchronized {

 /**
  * @param args
  */
 public static void main(String[] args) {
  new TraditionalThreadSynchronized().init();
 }
 
 public void init(){
  final Outputer outputer = new Outputer();
    new Thread(new Runnable(){
             
   @Override
   public void run() {
    
    while(true){
               try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    outputer.output("zhangxiaoxiang");
    }
   }
     
     
    }).start();
    
    new Thread(new Runnable(){
            
   @Override
   public void run() {
    while(true){
               try {
     Thread.sleep(100);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    outputer.output("lihuoming");
    }
   }
     
     
    }).start();
 }
 private static class Outputer {
  //必须保证用同一个监视器对象,才能起到互斥作用
  public void output(String name){
   synchronized(Outputer.this){
    int len = name.length();
    for(int i = 0;i<len;i++){
     System.out.print(name.charAt(i));
    }
    System.out.println();
   }
   
  }
  public synchronized void output2(String name){
  
    int len = name.length();
    for(int i = 0;i<len;i++){
     System.out.print(name.charAt(i));
    }
    System.out.println();
   
   
  }
  public static synchronized void output3(String name){
   
    int len = name.length();
    for(int i = 0;i<len;i++){
     System.out.print(name.charAt(i));
    }
    System.out.println();
   
   
  }
 }
}


2.线程间的通讯

eg: 子循环先运行10次,然后主循环运行100次,然后回到子循环10次.如此循环50次

 public class ThreadTest { 
public static void main(String[] args) {
  stubnew ThreadTest().init(); 
}
public void init() {
final Business business = new Business();
new Thread(new Runnable() {
      publicvoid run() {
     for(int i=0;i<50;i++) {
      business.SubThread(i); } } } ).start();
      for(int i=0;i<50;i++) { business.MainThread(i); } 
    }
private class Business {booleanbShouldSub = true;//这里相当于定义了控制该谁执行的一个信号灯
   public synchronized void MainThread(int i) {
      if(bShouldSub)
     try {
       this.wait(); 
     } catch (InterruptedException e) 
        {// TODO Auto-generated catch block 
         e.printStackTrace(); 
         } 
       for(int j=0;j<5;j++) { 
        System.out.println(Thread.currentThread().getName() + ":i=" + i +",j=" + j); }
        bShouldSub = true;this.notify(); }
    public synchronizedvoid SubThread(int i) 
    {
       if(!bShouldSub)
       try {this.wait(); 
    } catch (InterruptedException e) {// TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     for(int j=0;j<10;j++) { 
        System.out.println(Thread.currentThread().getName() + ":i=" + i +",j=" + j); }
      bShouldSub = false; this.notify(); } 
 }}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值