您的位置:首页 > 编程语言 > Java开发

java笔记:熟练掌握线程技术---基础篇(上)

2011-12-16 13:36 573 查看
  最近一直在看提升javascript代码性能的资料,看来看去就是为了如何提升网站的并发能力或者是软件如何对海量数据进行处理,这里我不想探讨解决这些难题的解决方案,但要解决并发或者是海量数据的问题一定离不开线程,线程的确相当的重要,当你要满足日新月异的用户需求而你所做的软件没有好好利用线程的知识绝对是一件无法让人接受的,就算你是一个关注前端技术的工程师也不会幸免对线程的运用,我相信不到三年我们的主流浏览器都会或多或少有类似的线程开发模型。同时线程也是面试最爱问的问题,线程的确可以很好的衡量一个程序员水平的技术难点,对于一个关注技术的工程师,想把软件真正做好,一定要熟练掌握好线程,我就从今天开始好好复习下线程的知识。

  我主要的工作语言是java,我就从java里的线程技术讲起。

  在java里创建线程有两种方式,一种是继承Thread类,另一种是实现Runnable接口

  第一种创建线程的方法:继承Thread类

  Thread类最重要的方法是run(),你如果想实现线程你就得覆盖这个方法,run里面的内容就是你要实现线程所具有的功能。而Thread里的run方法总会以某种形式进行循环,如果run方法里没有跳出循环的条件,线程将会一直运行下去。编写好一个线程对象后,对象要通过start()方法启动线程,构建的线程对象如果不调用start()方法,线程将永远都不会执行run方法里写好的业务逻辑。

  下面是一个最简单的线程实例:

View Code

package cn.com.sxia;

import java.util.concurrent.CountDownLatch;

class InnerThread1{
private int countDown = 5;
private Inner inner;

private class Inner extends Thread{
Inner(String name) {
super(name);
start();
}

public void run(){
while(true){
System.out.println(this);
if (--countDown == 0)
return;

try {
sleep(10);
} catch (InterruptedException e) {

e.printStackTrace();
}
}
}

public String toString(){
return getName() + ": " + countDown;
}
}

public InnerThread1(String name)
{
inner = new Inner(name);
}
}

class InnerThread2{
private int countDown = 5;
private Thread t;

public InnerThread2(String name)
{
t = new Thread(name){
public void run(){
while(true)
{
System.out.println(this);
if (--countDown == 0)
return;

try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public String toString(){
return getName() + ": " + countDown;
}
};
t.start();
}
}

class InnerRunnable1{
private int countDown = 5;
private Inner inner;

private class Inner implements Runnable{

Thread t;

public Inner(String name) {
t = new Thread(this,name);
t.start();
}

@Override
public void run() {
while(true){
System.out.println(this);
if (--countDown == 0)
return;

try {
Thread.sleep(10);
} catch (InterruptedException e) {

e.printStackTrace();
}
}
}

public String toString(){
return t.getName() + ": " + countDown;
}
}

public InnerRunnable1(String name)
{
inner = new Inner(name);
}
}

class InnerRunnable2{
private int countDown = 5;
private Thread t;

public InnerRunnable2(String name)
{
t = new Thread(new Runnable() {

@Override
public void run() {
while(true){
System.out.println(this);
if (--countDown == 0)
return;

try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

public String toString(){
return Thread.currentThread().getName() + ": " + countDown;
}
},name);
t.start();
}
}

class ThreadMethod{
private int countDown = 5;
private Thread t;
private String name;

public ThreadMethod(String name){
this.name = name;
}

public void runThread(){
if (t == null){
t = new Thread(name){
public void run(){
while(true)
{
System.out.println(this);
if (--countDown == 0)
return;

try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

public String toString(){
return getName() + ": " + countDown;
}
};
t.start();
}
}
}

public class ThreadVariations {

public static void main(String[] args) {
new InnerThread1("InnerThread1");
new InnerThread2("InnerThread2");
new InnerRunnable1("InnerRunnable1");
new InnerRunnable2("InnerRunnable2");
new ThreadMethod("ThreadMethod").runThread();
}

}


  结果如下:

InnerThread1: 5
InnerThread2: 5
InnerRunnable1: 5
InnerRunnable2: 5
InnerThread1: 4
ThreadMethod: 5
InnerRunnable1: 4
InnerRunnable2: 4
InnerThread1: 3
ThreadMethod: 4
InnerRunnable1: 3
InnerRunnable2: 3
InnerThread1: 2
ThreadMethod: 3
InnerRunnable1: 2
InnerRunnable2: 2
InnerThread1: 1
ThreadMethod: 2
InnerRunnable1: 1
InnerRunnable2: 1
ThreadMethod: 1
InnerThread2: 4
InnerThread2: 3
InnerThread2: 2
InnerThread2: 1


  第一个InnerThread1类里面创建了一个内部类,在InnerThread1的构造函数里构建了这个内部类,其实我们往往只是希望某一个对象具有线程的功能,因此单独构造一个继承Thread类的类是不是有这个必要是值得商榷的。所以我们有了第二个类的做法了,我们在InnerThread2的构造函数里建立了一个匿名内部类,他继承了Thread,这样我们既让自定义的类具有了线程的功能,又隐藏了不必要的细节,这种做法更合理了。至于第三个和第四个类是换了Runnable来实现同样的功能,但是看起来比较繁琐哈。而ThreadMethod类展示了如何在方法内部创建线程,这种做法的应用场景是,一个类主干可能不需要多线程的,但是它的某个功能可能需要多线程,那么把线程放到方法里是很有必要的,这种方法很值得推广,我们将线程的功能精确到方法级别也许会让我们的程序更加好控制也更加的健壮

  线程的基础篇上篇内容结束了,下一篇我将讲多线程共享资源的问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: