------- android培训、java培训、期待与您交流! ----------
创建线程的两种方式:
Thread类中的两个最主要的方法:
(1)run()—包含线程运行时所执行的代码,即线程需要完成的任务,是线程
执行体。
(2)start()—用于启动线程
1、通过继承Thread类来创建并启动多线 程的步骤:
(1)定义Thread类的子类,并覆盖该类的run()方法。
(2)创建Thread子类的实例,即创建线程对象。
(3)用线程对象的start()方法来启动该线程。
示例代码:
public class Thread1 extends Thread{ public void run(){ System.out.println(this.getName()); } public static void main(String args[]){ System.out.println(Thread.currentThread().getName()); Thread1 thread1 = new Thread1(); Thread1 thread2 = new Thread1(); thread1.start(); thread2.start(); } }
|
2、实现Runnable接口创建线程类
实现Runnable接口的类必须使用Thread类的实例才能创建线程。通过实现Runnable接口来创建并启动多线程的步骤:
(1)定义Runnable接口的实现类,并实现该接口的run()方法。
(2)创建Runnable实现类的实例,然后将该实例作为参数传入Thread类的构造方法来创建Thread对象。
(3)用线程对象的start()方法来启动该线程。
public class MyRunnable implements Runnable{ public void run(){ System.out.println(Thread.currentThread().getName()); } public static void main(String args[]){ MyRunnable r1 = new MyRunnable(); MyRunnable r2 = new MyRunnable(); MyRunnable r3 = new MyRunnable(); Thread thread1 = new Thread(r1,"MyThread1"); //创建线程时为其命名 Thread thread2 = new Thread(r2); thread2.setName("MyThread2"); //通过setName()方法为线程命名 Thread thread3 = new Thread(r3); //不命名的话系统会给线程以默认的名字 thread1.start(); thread2.start(); thread3.start(); } } |
三、两种创建线程方式的比较
采用继承Thread类方式:
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类(即会受到java单继承的局限)。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标(target)对象,
所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了
面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。
提示:在实际开发中,一般采用实现Runnable接口的方式来创建线程类,因为它具有更好的灵活性和可扩展性。
线程中的同步和互斥:
下面我们来总结一下synchronized语句(同步代码块儿),
synchronized方法(同步方法)以及静态同步方法的一些知识
public class TraditionalThreadSynchyonized {
public static void main(String[] args) { final Outputer outputer=new Outputer(); new Thread(new Runnable(){ public void run() { while(true) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } outputer.output1("liuhongjian"); } } }).start();
new Thread(new Runnable(){ public void run() { while(true) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } outputer.output2("LANJIAOJIAOLANJIAOJIAOLANJIAOJIAO"); } } }).start();
new Thread(new Runnable(){ public void run() { while(true) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } outputer.output3("-----liuhongjian-------"); } } }).start();
} }
class Outputer { Public void output1(String name) { int len=name.length(); synchronized (Outputer.class) {//同步代码块儿的示例
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(); } } |
以上代码是验证:同步函数用的是this锁,静态同步函数用的
是此静态同步函数所在的类的字节码对象锁即Outputer.class
而同步代码块儿synchronized(object obj)即他所用的锁是人
为指定的。要实现互斥必须保证用的是同一把锁!!
线程间共享数据:
这是把资源封装成一个Resouce类,在不同的Runnable中实现互斥
和线程间的通信的代码示例:
class Resouce { private String name; private String sex; boolean flag=true; public void setName(String name) { this.name=name; } public String getName() { return this.name; } public void setSex(String sex) { this.sex=sex; } public String getSex() { return this.sex; } }
class Inputer implements Runnable { private Resouce r; Inputer(Resouce r) { this.r=r; } public void run() { int x=0; while(true) { synchronized(r) { if(r.flag) { try{r.wait(); } catch (Exception e){} } if(x==0) { r.setName("zhangsan"); r.setSex("man"); } else { r.setName("丽丽"); r.setSex("女"); } x=(x+1)%2; r.flag=true; r.notify(); } } } }
class Outputer implements Runnable { private Resouce r; Outputer (Resouce r) { this.r=r; } public void run() { while(true) { synchronized(r) { if(!r.flag) { try{r.wait(); } catch (Exception e){} } System.out.println(r.getName()+ "....."+r.getSex()); r.flag=false; r.notify(); } } } } class ThreadShareData2 { public static void main(String[] args) { Resouce r=new Resouce(); Outputer out=new Outputer(r); Inputer input=new Inputer(r);
new Thread(out).start(); new Thread(input).start();
} } |