什么线程:就是程序的一条执行线索
创建的方式有两种:
package com.water.heima; public class TraditionalThread { public static void main(String[] args) { //第一种分析 Thread thread = new Thread(){ @Override public void run(){ System.out.println("Thread1 start"); while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("1:" + Thread.currentThread().getName()); System.out.println("2:" + this.getName()); } } }; thread.start(); //第二种分析 Thread thread2 = new Thread(new Runnable() { @Override public void run() { System.out.println("Thread2 start"); while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("1:" + Thread.currentThread().getName()); } } }); thread2.start(); //第三种情况分析 new Thread(new Runnable() { @Override public void run() { System.out.println("Thread4 start"); while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread:" + Thread.currentThread().getName()); } } }){ //加上这个重写,就不会掉父类的run方法了,就不会执行runnable中的run了 @Override public void run(){ System.out.println("Thread3 start"); while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread:" + Thread.currentThread().getName()); } } }.start(); } }
思考题:多线程机制会提高程序的运行效率吗?为什么会有多线程下载呢?
打个比喻,让你一个人做馒头,给你一张桌子做快,还是给你三个桌子做快,是一张桌子做的快,下载文件,一次把所有下下来,比分别下单个文件下。
多线程下载文件是你占用了服务器端更多带宽才下载的快
定时器的应用
Timer类
TimerTask类
package com.water.heima; import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class TraditionalTimerTest { static int count = 0; @SuppressWarnings("deprecation") public static void main(String[] args) { //10秒之后爆炸,以后每隔3秒炸一次(第一种形式) new Timer().schedule(new TimerTask() { @Override public void run() { System.out.println("bombing!"); } }, 10000, 3000); //第二种方式考虑(这种情况只炸两次) new Timer().schedule(new TimerTask() { @Override public void run() { System.out.println("bombing!"); //炸弹里面还有炸弹(母蛋、子蛋) new Timer().schedule(new TimerTask() { @Override public void run() { System.out.println("bombing!"); } }, 2000); } }, 2000); //第三种方式考虑(不停的炸) class MyTimerTask extends TimerTask{ @Override public void run() { System.out.println("bombing!"); //炸弹里面还有炸弹(母蛋、子蛋) new Timer().schedule(new MyTimerTask(), 2000); } }; new Timer().schedule(new MyTimerTask(), 2000); //第四种情况(炸弹交替爆炸,2秒爆炸和4秒爆炸), //解决方式两种1.静态变量,2两个炸弹 //内部类不能声明静态变量 class MyTimerTask2 extends TimerTask{ @Override public void run() { count = (count + 1)%2; System.out.println("bombing!"); //炸弹里面还有炸弹(母蛋、子蛋) new Timer().schedule(new MyTimerTask2(), 2000); } }; new Timer().schedule(new MyTimerTask2(), 2000 + 2000 * count); //不加下面这段代码,炸弹会炸么(会) while(true){ System.out.println(new Date().getSeconds()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //开源的工具quartz(定时工具),工具更强大(15分钟可以学会),知道这个知识就是一个很大的进步 }
线程的互斥与同步通讯(编写多线程的时候)
线程安全问题可以用(银行转账可以解释)
package com.water.heima; public class TraditionalThreadSynchronized { Outputer outputer = new Outputer(); public static void main(String[] args) { new TraditionalThreadSynchronized().init(); } public void init(){ final Outputer outputer = new Outputer(); new Thread(new Runnable() { @Override public void run() { while(true){ try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } outputer.output("zhangxiaoxiang"); } } }).start(); new Thread(new Runnable() { @Override public void run() { while(true) { try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } outputer.output("lihuoming"); } } }).start(); } static class Outputer{ //就和厕所里一个坑,只能允许一个人进去 //需要声明原子性(任何一个对象当作门闩) //创建一个门闩 //上面outputer.output都是一个对象 String xx = ""; public void output(String name) { int len = name.length(); //name就是门闩(不过name,不是一个对象的变量,就会出问题) //这个xx可以换成this(就不用xx了) synchronized (xx) { for (int i = 0; i < len; i++){ System.out.print(name.charAt(i)); } System.out.println(); } } //这种方式也可以(第二种方式)(这种形式用的门闩是this) public synchronized void output2(String name) { int len = name.length(); //name就是门闩(不过name,不是一个对象的变量,就会出问题) //这个xx可以换成this(就不用xx了) 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(); //name就是门闩(不过name,不是一个对象的变量,就会出问题) //这个xx可以换成this(就不用xx了) for (int i = 0; i < len; i++){ System.out.print(name.charAt(i)); } System.out.println(); } } }
子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序
转载请注明:学时网 » java 多线程学习总结