当前位置:  编程技术>移动开发
本页文章导读:
    ▪Thread-join()        Thread--join() 转自http://blog.csdn.net/bzwm/archive/2009/02/12/3881392.aspx一、在研究join的用法之前,先明确两件事情。1.join方法定义在Thread类中,则调用者必须是一个线程,例如:Thread t = new CustomThread.........
    ▪ widget -listView        widget ----listView listView = new ListView(this); prepareData(); //适配器提供 data到layout的接口 SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, android.R.layout.simple_list_item_2, new String[]{"性别","姓名"}, new .........
    ▪ 自定义信箱发送邮件以及普通发送邮件       自定义邮箱发送邮件以及普通发送邮件 Intent emailIntent = new Intent(Intent.ACTION_SEND);   emailIntent.setType("text/html");  emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,sendTo );   emailIntent.putExtra(android.conte.........

[1]Thread-join()
    来源: 互联网  发布时间: 2014-02-18
Thread--join()
转自http://blog.csdn.net/bzwm/archive/2009/02/12/3881392.aspx



一、在研究join的用法之前,先明确两件事情。

1.join方法定义在Thread类中,则调用者必须是一个线程,

例如:

Thread t = new CustomThread();//这里一般是自定义的线程类

t.start();//线程起动

t.join();//此处会抛出InterruptedException异常



2.上面的两行代码也是在一个线程里面执行的。



以上出现了两个线程,一个是我们自定义的线程类,我们实现了run方法,做一些我们需要的工作;另外一个线程,生成我们自定义线程类的对象,然后执行

customThread.start();

customThread.join();

在这种情况下,两个线程的关系是一个线程由另外一个线程生成并起动,所以我们暂且认为第一个线程叫做“子线程”,另外一个线程叫做“主线程”。



二、为什么要用join()方法

主线程生成并起动了子线程,而子线程里要进行大量的耗时的运算(这里可以借鉴下线程的作用),当主线程处理完其他的事务后,需要用到子线程的处理结果,这个时候就要用到join();方法了。





三、join方法的作用

在网上看到有人说“将两个线程合并”。这样解释我觉得理解起来还更麻烦。不如就借鉴下API里的说法:

“等待该线程终止。”

解释一下,是主线程(我在“一”里已经命名过了)等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。(Waits for this thread to die.)





四、用实例来理解

写一个简单的例子来看一下join()的用法,一共三个类:

1.CustomThread 类

2. CustomThread1类

3. JoinTestDemo 类,main方法所在的类。



代码1:

view plaincopy to clipboardprint?
package wxhx.csdn2; 
/**

* @author bzwm
*
*/ 
class CustomThread1 extends Thread { 
    public CustomThread1() { 
        super("[CustomThread1] Thread"); 
    }; 
    public void run() { 
        String threadName = Thread.currentThread().getName(); 
        System.out.println(threadName + " start."); 
        try { 
            for (int i = 0; i < 5; i++) { 
                System.out.println(threadName + " loop at " + i); 
                Thread.sleep(1000); 
            } 
            System.out.println(threadName + " end."); 
        } catch (Exception e) { 
            System.out.println("Exception from " + threadName + ".run"); 
        } 
    } 

class CustomThread extends Thread { 
    CustomThread1 t1; 
    public CustomThread(CustomThread1 t1) { 
        super("[CustomThread] Thread"); 
        this.t1 = t1; 
    } 
    public void run() { 
        String threadName = Thread.currentThread().getName(); 
        System.out.println(threadName + " start."); 
        try { 
            t1.join(); 
            System.out.println(threadName + " end."); 
        } catch (Exception e) { 
            System.out.println("Exception from " + threadName + ".run"); 
        } 
    } 

public class JoinTestDemo { 
    public static void main(String[] args) { 
        String threadName = Thread.currentThread().getName(); 
        System.out.println(threadName + " start."); 
        CustomThread1 t1 = new CustomThread1(); 
        CustomThread t = new CustomThread(t1); 
        try { 
            t1.start(); 
            Thread.sleep(2000); 
            t.start(); 
            t.join();//在代碼2里,將此處注釋掉 
        } catch (Exception e) { 
            System.out.println("Exception from main"); 
        } 
        System.out.println(threadName + " end!"); 
    } 




打印结果:



main start.//main方法所在的线程起动,但没有马上结束,因为调用t.join();,所以要等到t结束了,此线程才能向下执行。

[CustomThread1] Thread start.//线程CustomThread1起动

[CustomThread1] Thread loop at 0//线程CustomThread1执行

[CustomThread1] Thread loop at 1//线程CustomThread1执行

[CustomThread] Thread start.//线程CustomThread起动,但没有马上结束,因为调用t1.join();,所以要等到t1结束了,此线程才能向下执行。

[CustomThread1] Thread loop at 2//线程CustomThread1继续执行

[CustomThread1] Thread loop at 3//线程CustomThread1继续执行

[CustomThread1] Thread loop at 4//线程CustomThread1继续执行

[CustomThread1] Thread end. //线程CustomThread1结束了

[CustomThread] Thread end.// 线程CustomThread在t1.join();阻塞处起动,向下继续执行的结果

main end!//线程CustomThread结束,此线程在t.join();阻塞处起动,向下继续执行的结果。



修改一下代码,得到代码2:(这里只写出修改的部分)

view plaincopy to clipboardprint?
public class JoinTestDemo { 
    public static void main(String[] args) { 
        String threadName = Thread.currentThread().getName(); 
        System.out.println(threadName + " start."); 
        CustomThread1 t1 = new CustomThread1(); 
        CustomThread t = new CustomThread(t1); 
        try { 
            t1.start(); 
            Thread.sleep(2000); 
            t.start(); 
//          t.join();//在代碼2里,將此處注釋掉 
        } catch (Exception e) { 
            System.out.println("Exception from main"); 
        } 
        System.out.println(threadName + " end!"); 
    } 




打印结果:



main start. // main方法所在的线程起动,但没有马上结束,这里并不是因为join方法,而是因为Thread.sleep(2000);

[CustomThread1] Thread start. //线程CustomThread1起动

[CustomThread1] Thread loop at 0//线程CustomThread1执行

[CustomThread1] Thread loop at 1//线程CustomThread1执行

main end!// Thread.sleep(2000);结束,虽然在线程CustomThread执行了t1.join();,但这并不会影响到其他线程(这里main方法所在的线程)。

[CustomThread] Thread start. //线程CustomThread起动,但没有马上结束,因为调用t1.join();,所以要等到t1结束了,此线程才能向下执行。

[CustomThread1] Thread loop at 2//线程CustomThread1继续执行

[CustomThread1] Thread loop at 3//线程CustomThread1继续执行

[CustomThread1] Thread loop at 4//线程CustomThread1继续执行

[CustomThread1] Thread end. //线程CustomThread1结束了

[CustomThread] Thread end. // 线程CustomThread在t1.join();阻塞处起动,向下继续执行的结果





五、从源码看join()方法



在CustomThread的run方法里,执行了t1.join();,进入看一下它的JDK源码:

view plaincopy to clipboardprint?
public final void join() throws InterruptedException { 
n(0); 


然后进入join(0)方法:



view plaincopy to clipboardprint?
   /**
    * Waits at most <code>millis</code> milliseconds for this thread to 
    * die. A timeout of <code>0</code> means to wait forever. //注意这句
    *
    * @param      millis   the time to wait in milliseconds.
    * @exception  InterruptedException if another thread has interrupted
    *             the current thread.  The <i>interrupted status</i> of the
    *             current thread is cleared when this exception is thrown.
    */ 
   public final synchronized void join(long millis) //参数millis为0. 
   throws InterruptedException { 
long base = System.currentTimeMillis(); 
long now = 0; 
if (millis < 0) { 
           throw new IllegalArgumentException("timeout value is negative"); 

if (millis == 0) {//进入这个分支 
    while (isAlive()) {//判断本线程是否为活动的。这里的本线程就是t1. 
    wait(0);//阻塞 
    } 
} else { 
    while (isAlive()) { 
    long delay = millis - now; 
    if (delay <= 0) { 
        break; 
    } 
    wait(delay); 
    now = System.currentTimeMillis() - base; 
    } 

   } 







单纯从代码上看,如果线程被生成了,但还未被起动,调用它的join()方法是没有作用的。将直接继续向下执行,这里就不写代码验证了。

    
[2] widget -listView
    来源: 互联网  发布时间: 2014-02-18
widget ----listView
listView = new ListView(this);
prepareData();
//适配器提供 data到layout的接口
SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, android.R.layout.simple_list_item_2,
new String[]{"性别","姓名"}, new int[]{R.id.text1,R.id.text2}); //只显示性别对应的数据

listView.setAdapter(simpleAdapter);

setContentView(listView);

listView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//parent.getItemAtPosition(position)会得到对应这行的data
setTitle(parent.getItemAtPosition(position).toString());  //这里title将取到全部数据
}
});


//==============技巧,因为listView能展现出来,说明Cursor已经拿到了,所以取数据可以通过Cursot==========================

Cursor c = mTrackCursor;
c.moveToPosition(position);
Intent i = new Intent(this, ShowTrack.class);
i.putExtra(TrackDbAdapter.KEY_ROWID, id);
i.putExtra(TrackDbAdapter.NAME, c.getString(c
.getColumnIndexOrThrow(TrackDbAdapter.NAME)));
i.putExtra(TrackDbAdapter.DESC, c.getString(c
.getColumnIndexOrThrow(TrackDbAdapter.DESC)));

c.getString()为得到某个索引的值

    
[3] 自定义信箱发送邮件以及普通发送邮件
    来源: 互联网  发布时间: 2014-02-18
自定义邮箱发送邮件以及普通发送邮件

Intent emailIntent = new Intent(Intent.ACTION_SEND);   emailIntent.setType("text/html"); 
 emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,sendTo ); 
 
 emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "test" ); 
 emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "msg" ); 
2.必须使用外部java mail library 以及写一个 类似下面的helper class

 

public class GMailSender extends javax.mail.Authenticator { 
 private String mailhost = "smtp.gmail.com"; 
 private String user; 
 private String password; 
 private Session session; 
 
 static { 
  Security.addProvider(new JSSEProvider()); 
 } 
 
 public GMailSender(String user, String password) { 
  this.user = user; 
  this.password = password; 
 
  Properties props = new Properties(); 
  props.setProperty("mail.transport.protocol", "smtp"); 
  props.setProperty("mail.host", mailhost); 
  props.put("mail.smtp.auth", "true"); 
  props.put("mail.smtp.port", "465"); 
  props.put("mail.smtp.socketFactory.port", "465"); 
  props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
  props.put("mail.smtp.socketFactory.fallback", "false"); 
  props.setProperty("mail.smtp.quitwait", "false"); 
 
  session = Session.getDefaultInstance(props, this); 
 } 
 
 protected PasswordAuthentication getPasswordAuthentication() { 
  return new PasswordAuthentication(user, password); 
 } 
 
 public synchronized void sendMail(String subject, String body, String sender, String recipients) throws Exception { 
  MimeMessage message = new MimeMessage(session); 
  DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain")); 
  message.setSender(new InternetAddress(sender)); 
  message.setSubject(subject); 
  message.setDataHandler(handler); 
  if (recipients.indexOf(',') > 0) 
   message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients)); 
  else 
   message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients)); 
  Transport.send(message); 
 } 
 
 public class ByteArrayDataSource implements DataSource { 
  private byte[] data; 
  private String type; 
 
  public ByteArrayDataSource(byte[] data, String type) { 
   super(); 
   this.data = data; 
   this.type = type; 
  } 
 
  public ByteArrayDataSource(byte[] data) { 
   super(); 
   this.data = data; 
  } 
 
  public void setType(String type) { 
   this.type = type; 
  } 
 
  public String getContentType() { 
   if (type == null) 
    return "application/octet-stream"; 
   else 
    return type; 
  } 
 
  public InputStream getInputStream() throws IOException { 
   return new ByteArrayInputStream(data); 
  } 
 
  public String getName() { 
   return "ByteArrayDataSource"; 
  } 
 
  public OutputStream getOutputStream() throws IOException { 
   throw new IOException("Not Supported"); 
  } 
 } 

Sending the email is t


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3