1.Java创建与启动线程
Java提供两种方式创建和启动线程:1.直接Thread类,2.实现Runable接口。
1.1 继承Thread类
public class myThread extends Thread {
public void run(){
for(int i=0;i<5;i++){
System.out.println(this.getName()+":"+i);
}
}
public static void main(String[] args){
//创建3个线程
myThread myThread1 = new myThread();
myThread myThread2 = new myThread();
myThread myThread3 = new myThread();
//启动线程
myThread1.start();
myThread2.start();
myThread3.start();
}
}
线程1,2,3,随机执行
注意启动线程一定要用thread.start()而不能用thread.run()。否则则是顺序执行,失去多线程的意义。
public class myThread extends Thread {
public void run(){
for(int i=0;i<5;i++){
System.out.println(this.getName()+":"+i);
}
}
public static void main(String[] args){
//创建3个线程
myThread myThread1 = new myThread();
myThread myThread2 = new myThread();
myThread myThread3 = new myThread();
//启动线程
myThread1.run();
myThread2.run();
myThread3.run();
}
}
输出结果:三个线程顺序执行
1.2 实现Runnable接口实现
public class myRunnable implements Runnable {
private String name;
public void run() {
for(int i=0;i<5;i++){
System.out.println(this.getName()+":"+i);
}
}
public String getName() {
return name;
}
public myRunnable(String name) {
super();
this.name = name;
}
public static void main(String[] args){
//创建3个线程
myRunnable myRunnable1 = new myRunnable("thread1");
myRunnable myRunnable2 = new myRunnable("thread2");
myRunnable myRunnable3 = new myRunnable("thread3");
//启动线程,由于runnable中是没有start方法的,这里要将你的runnable实例作为Thread(Target target)参数,启动线程
//多个Runnable实例,执行相同代码
new Thread(myRunnable1).start();
new Thread(myRunnable2).start();
new Thread(myRunnable3).start();
}
}
执行结果:随机执行
2.两种方式有什么不同,再看下面的代码,利用Runnable 实现资源共享,这里的共享知识部分共享
比如售票系统
1 public class myThread extends Thread {
2 private int tickets=5;//总共5张票
3 public void run(){
4 for(int i=0;i<10;i++){
5 if(tickets>0){
6 System.out.println(this.getName()+":"+tickets--);
7 }
8 }
9 }
10
11 public static void main(String[] args){
12 //创建3个线程
13 myThread myThread1 = new myThread();
14 myThread myThread2 = new myThread();
15 myThread myThread3 = new myThread();
16 //启动线程
17 myThread1.start();
18 myThread2.start();
19 myThread3.start();
20 }
21 }
输出结果:每个线程都卖了5张票,相当于15张票
那么再来看看使用Runnable 实现三个进程共享系统中的5张票
public class myRunnable implements Runnable {
private int tickets=5;
public void run() {
for(int i=0;i<10;i++){
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"正在卖票:"+tickets--);
}
}
}
public static void main(String[] args){
//创建3个线程
myRunnable myRunnable1 = new myRunnable();
//启动线程,由于runnable中是没有start方法的,这里要将你的runnable实例作为Thread(Target target)参数,启动线程
//通过一个Runnable实例,创建3个线程,该三个线程共享tickets这个资源
new Thread(myRunnable1,"1号窗口").start();
new Thread(myRunnable1,"2号窗口").start();
new Thread(myRunnable1,"3号窗口").start();
}
}
输出结果:三个线程共享了5张票
利用实例化一个Runnable对象,实现共享
3.大家注意了,多线程开发中,主线程和子线程是并发执行的,也就是,子线程在执行的过程中,主线程也在往下执行。这就导致了有这么一个需求不好实现。那就是,主线程需要所有子线程返回执行结果才能继续执行。同志们这个怎么实现呢?
ok,我们利用一个CountDownLatch来实现
1 public class MyRunnableReturn implements Runnable {
2 private CountDownLatch threadsSingal;
3
4
5 public MyRunnableReturn(CountDownLatch threadsSingal) {
6 super();
7 this.threadsSingal = threadsSingal;
8 }
9
10
11 public void run() {
12 System.out.println(Thread.currentThread().getName()+"--开始");
13 System.out.println(Thread.currentThread().getName()+"--结束");
14 threadsSingal.countDown();//线程减1
15 }
16
17 public static void main(String [] agrs){
18 System.out.println("Main --开始");
19 CountDownLatch threadsSingal=new CountDownLatch(3);
20 MyRunnableReturn myRunnable=new MyRunnableReturn(threadsSingal);
21 new Thread(myRunnable,"thread1").start();
22 new Thread(myRunnable,"thread2").start();
23 new Thread(myRunnable,"thread3").start();
24 try {
25 threadsSingal.await();//等待所有子线程执行完
26 } catch (InterruptedException e) {
27 // TODO Auto-generated catch block
28 e.printStackTrace();
29 }
30 System.out.println("Main --结束");
31 }
32 }
输出结果:主线程等待所有子线程执行完毕,然后在执行
4.问题又来了,现实开发中,有可能,需要不同Runnable根据不同的数据执行相同的代码,这个又如何实现呢?
这就又导致了,通过只实例化一个Runnable对象来进行共享资源的方法不可行了。我们可以通过将共享数据封装成一个对象,传给不同的Runnable线程对象。达到资源共享