Java学习 之 多线程

  1 /*
  2 
  3 线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程,一个进程中是可以有多个线程的,这个应用程序称之为多线程
  4 
  5 单线程:即有多个任务只能依次执行,当上个任务执行结束后,下个任务开始执行
  6 
  7 多线程:即有多个任务可以同时执行
  8 
  9 主线程:jvm启动后,必然有一个执行路径(线程)从main方法开始,一直执行到main方法结束,这个线程在java中称之为主线程
 10 
 11 多线程:多线程执行时,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间,进行方法的压栈和弹栈
 12 
 13 */
 14 
 15 /*
 16 
 17 Thread类:
 18 
 19 构造方法:Thread()分配新的Thread对象
 20 
 21                 Thread(String name)分配新的Thread对象,将指定的name作为其线程名称
 22 
 23 方法: void  start()使线程开始执行,虚拟机调用该线程的run方法
 24 
 25           void run()该线程要执行的操作
 26 
 27           static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠
 28 
 29 创建新执行线程的两种方法:
 30 
 31    1、将类声明为Thread的子类,该子类重写Thread类的run方法,创建对象,开启线程,run方法相当于其他线程的main方法
 32 
 33    2、声明一个实现Runnable接口的类,该类然后实现run方法,然后创建Runnable的子类对象,传入到某个线程的构造方法中,开启线程
 34 
 35 */
 36 
 37 public class Demo1{
 38 
 39      public static void main(String[] args){
 40 
 41         //创建自定义线程对象
 42 
 43        MyThread mt = new MyThread("新线程");
 44 
 45       //开启线程
 46 
 47        mt.start();
 48 
 49       //在主方法中执行for循环
 50 
 51      for(int i = 0 ; i < 10 ; i++){
 52 
 53           System.out.println("main线程" + i);
 54 
 55     }
 56 
 57   }
 58 
 59 }
 60 
 61 //自定义线程类
 62 
 63 public class MyThread extends Thread{
 64 
 65      //定义指定线程名称的构造方法
 66 
 67     public MyThread(String name){
 68 
 69          //调用父类的String参数的构造方法,指定线程的名称
 70 
 71          super(name);
 72 
 73       }
 74 
 75      //重写run方法,完成该线程执行的逻辑
 76 
 77     @Override
 78 
 79     public void run(){
 80 
 81        for(int i = 0 ; i < 10 ; i++){
 82 
 83             System.out.println(getName() + "正在执行" + i);
 84          }
 85 
 86    }
 87 
 88 }
 89 
 90 /*
 91 
 92 获取线程名称:
 93 
 94          static Thread currentThread()返回对当前正在执行的线程对象的引用
 95 
 96          String getName()返回该线程的名称
 97 
 98 */
 99 
100 public class MyThread extends Thread{
101 
102    //重写run方法
103 
104    public void run(){
105 
106      for(int i = 0 ; i < 10 ; i++){
107 
108          System.out.println(Thread.currentThread().getName() +", i =" + i);
109 
110        }
111 
112     public MyThread(String name){
113 
114           super(name);
115 
116     }
117 
118     }
119 
120 }
121 
122 public class ThreadDemo{
123 
124     public staitc void main(String[] args){
125 
126       //创建两个线程任务
127 
128      MyThread mt = new MyThread();
129 
130      MyThread mt2 = new MyThread();
131 
132      mt.run();//没有开启新线程,在主线程调用run方法
133 
134      mt2.start();//开启一个新线程,新线程调用run方法
135 
136     }
137 
138 }
139 
140 /*
141 
142 实现Runnanle接口:
143 
144 接口中的方法: void run()使用实现接口Runnable的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的run方法
145 
146 Thread类构造方法:
147 
148      Thread(Runnable target)分配新的Thread对象,以便将target作为其运行对象
149 
150      Thread(Runnable target , String name)分配新的Thread对象,以便将target作为其运行对象,将指定的name作为其名称
151 
152 实现Runnable接口避免了单继承的局限性
153 
154 */
155 
156 public class RunnableDemo{
157 
158     public static void main(String[] args){
159 
160       //创建线程执行目标类对象
161 
162       Runnable run = new MyRunnable();
163 
164       //将Runnable接口的子类对象作为参数传递给Thread类的构造函数
165 
166       Thread t = new Thread(run);
167 
168       Thread t1 = new Thread(run);
169       //开启线程
170 
171      t.start();
172 
173      t1.start();
174 
175     for(int i = 0 ; i < 10 ; i++){
176 
177        System.out.println("main线程:" + i);
178 
179    }
180 
181    }
182 
183 }
184 
185 //自定义线程执行任务类
186 
187 public class MyRunnable implements Runnable{
188 
189      //定义线程要执行的run方法
190 
191     @Override
192 
193     public void run(){
194 
195        for(int i = 0 ; i < 10 ; i++){
196 
197            System.out.println("我的线程:" + i);
198 
199        }
200 
201    }
202 
203 }
204 
205 /*
206 
207 线程的匿名内部类:使用线程的匿名内部类方式,可以方便的实现每个线程执行不同的线程任务操作
208 */
209 
210         new Thread(){
211 
212               public void run(){
213 
214                  for(int i = 0 ; i < 10 ; i++){
215 
216                         System.out.println(Thread.currentThread().getName() +" i :"+ i);
217 
218                  }
219 
220             }
221 
222          }.start();
223 
224 
225 
226          Runnable r = new Runnable(){
227 
228                public void run(){
229 
230                    for(int i =0 ; i < 10 ; i++){
231 
232                          System.out.println(Thread.currentThread().getName());
233 
234                     }
235 
236                 }
237 
238          };
239 
240         new Thread(r).start();
241 
242 /*
243 
244 线程池:就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源
245 
246 Executors:线程池创建工厂类
247 
248    public static ExecutorService newFixedThreadPool(int nThread)返回线程池对象
249 
250 ExecutorService:线程池类
251 
252   Future<?> submit(Runnable task)获取线程池中的某个一个线程对象,并执行
253 
254 Future接口:用来记录线程任务执行完毕后产生的结果,线程池创建与使用
255 
256 */
257 
258 public class ThreadPoolDemo{
259 
260     public static void main(String[] args){
261 
262       //创建线程池对象
263 
264      ExecutorService es = Executors.newFixedThreadPool(2);//包含2个线程对象
265 
266      //创建Runnable实例对象
267 
268     MyRunnable mr = new MyRunnable();
269 
270     //从线程池中获取线程对象,然后调用MyRunnable中的run()
271 
272     es.submit(mr);
273 
274     //再获取个线程对象,调用MyRunnable中的run()
275 
276    es.submit(r);
277 
278    es.submit(r);
279 
280   //submit方法调用结束后,程序并不终止,因为线程池控制了线程的关闭,将使用完的线程又归还到了线程池中
281 
282   //关闭线程池
283 
284   es.shutdown();
285 
286    }
287 
288 }
289 
290 public class MyRunnable implements Runnable{
291 
292    @Override
293 
294    public void run(){
295 
296       System.out.println("abc");
297 
298       try{
299 
300           Thread.sleep(2000);
301 
302       }catch(Exception e){
303 
304            e.printStackTrace();
305 
306       }
307 
308       System.out.println("a" +Thread.currentThread().getName());
309 
310       System.out.println("bc");
311   }
312 
313 }
314 
315 /*
316 
317 Callable接口:与Runnable接口功能相似,用来指定线程任务,其中call()方法,用来返回线程任务执行完毕后的结果,call方法可抛异常
318 
319  ExecutorService:线程池类
320  <T>Future<T> submit(Callable<T> task)获取线程池中的某个一个线程对象,并执行线程中的call()方法
321 Future接口:用来记录线程任务执行完毕后产生的结果,线程池创建与使用
322 
323 */
324 
325 public class ThreadPoolDemo{
326 
327     public static void main(String[] args){
328 
329       //创建线程池对象
330 
331      ExecutorService es = Executors.newFixedThreadPool(2);//包含2个线程对象
332 
333      //创建Runnable实例对象
334 
335     MyCallable c = new MyCallable();
336 
337     //从线程池中获取线程对象,然后调用MyRunnable中的run()
338 
339     es.submit(c);
340 
341     //再获取个线程对象,调用MyCallable中的run()
342 
343    es.submit(c);
344 
345    es.submit(c);
346 
347   //submit方法调用结束后,程序并不终止,因为线程池控制了线程的关闭,将使用完的线程又归还到了线程池中
348 
349   //关闭线程池
350 
351   es.shutdown();
352 
353    }
354 
355 }
356 
357 public class MyCallable implements Callable{
358 
359     @Override
360 
361     public Object call() throws Exception{
362 
363       System.out.println("abc");
364 
365       Thread.sleep(2000);
366 
367       System.out.println("a:" + Thread.currentThread().getName());
368       System.out.println("bc");
369       return null;
370 
371    }
372 
373 }

 

posted @ 2020-04-24 20:56  蜡笔辛巴  阅读(217)  评论(0编辑  收藏  举报