A:Java程序运行原理java
B:JVM的启动是多线程的吗安全
package com.heima.thread; public class Demo1_Thread { /** * @param args * 证实jvm是多线程的 */ public static void main(String[] args) { for(int i = 0; i < 100000; i++) { new Demo(); } for(int i = 0; i < 10000; i++) { System.out.println("我是主线程的执行代码"); } } } class Demo { @Override public void finalize() { System.out.println("垃圾被清扫了"); } }
1.继承Thread服务器
public class Demo2_Thread { /** * @param args */ public static void main(String[] args) { MyThread mt = new MyThread(); //4,建立自定义类的对象 mt.start(); //5,开启线程 for(int i = 0; i < 3000; i++) { System.out.println("bb"); } } } class MyThread extends Thread { //1,定义类继承Thread public void run() { //2,重写run方法 for(int i = 0; i < 3000; i++) { //3,将要执行的代码,写在run方法中 System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaa"); } } }
package com.heima.thread; public class Demo2_Thread { /** * @param args */ public static void main(String[] args) { MyThread mt = new MyThread(); //4,建立Thread类的子类对象 mt.start(); //5,开启线程 for(int i = 0; i < 1000; i++) { System.out.println("bb"); } } } class MyThread extends Thread { //1,继承Thread public void run() { //2,重写run方法 for(int i = 0; i < 1000; i++) { //3,将要执行的代码写在run方法中 System.out.println("aaaaaaaaaaaa"); } } }
2.实现Runnable多线程
调用start()开启新线程, 内部会自动调用Runnable的run()方法并发
public class Demo3_Runnable { /** * @param args */ public static void main(String[] args) { MyRunnable mr = new MyRunnable(); //4,建立自定义类对象 //Runnable target = new MyRunnable(); Thread t = new Thread(mr); //5,将其看成参数传递给Thread的构造函数 t.start(); //6,开启线程 for(int i = 0; i < 3000; i++) { System.out.println("bb"); } } } class MyRunnable implements Runnable { //1,自定义类实现Runnable接口 @Override public void run() { //2,重写run方法 for(int i = 0; i < 3000; i++) { //3,将要执行的代码,写在run方法中 System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaa"); } } }
package com.heima.thread; public class Demo3_Thread { /** * @param args */ public static void main(String[] args) { MyRunnable mr = new MyRunnable(); //4,建立Runnable的子类对象 //Runnable target = mr; mr = 0x0011 Thread t = new Thread(mr); //5,将其看成参数传递给Thread的构造函数 t.start(); //6,开启线程 for(int i = 0; i < 1000; i++) { System.out.println("bb"); } } } class MyRunnable implements Runnable { //1,定义一个类实现Runnable @Override public void run() { //2,重写run方法 for(int i = 0; i < 1000; i++) { //3,将要执行的代码写在run方法中 System.out.println("aaaaaaaaaaaa"); } } }
package com.heima.thread; public class Demo4_Thread { /** * @param args */ public static void main(String[] args) { new Thread() { //1,继承Thread类 public void run() { //2,重写run方法 for(int i = 0; i < 1000; i++) { //3,将要执行的代码写在run方法中 System.out.println("aaaaaaaaaaaaaa"); } } }.start(); //4,开启线程 new Thread(new Runnable() { //1,将Runnable的子类对象传递给Thread的构造方法 public void run() { //2,重写run方法 for(int i = 0; i < 1000; i++) { //3,将要执行的代码写在run方法中 System.out.println("bb"); } } }).start(); //4,开启线程 } }
查看源码的区别:jvm
继承Threadide
继承Thread类函数
new Thread() { //1,new 类(){}继承这个类 public void run() { //2,重写run方法 for(int i = 0; i < 3000; i++) { //3,将要执行的代码,写在run方法中 System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaa"); } } }.start();
实现Runnable接口ui
new Thread(new Runnable(){ //1,new 接口(){}实现这个接口 public void run() { //2,重写run方法 for(int i = 0; i < 3000; i++) { //3,将要执行的代码,写在run方法中 System.out.println("bb"); } } }).start();
2.设置名字this
new Thread("xxx") { public void run() { for(int i = 0; i < 1000; i++) { System.out.println(this.getName() + "....aaaaaaaaaaaaaaaaaaaaaaa"); } } }.start(); new Thread("yyy") { public void run() { for(int i = 0; i < 1000; i++) { System.out.println(this.getName() + "....bb"); } } }.start();
Thread t1 = new Thread() { public void run() { for(int i = 0; i < 1000; i++) { System.out.println(this.getName() + "....aaaaaaaaaaaaaaaaaaaaaaa"); } } }; Thread t2 = new Thread() { public void run() { for(int i = 0; i < 1000; i++) { System.out.println(this.getName() + "....bb"); } } }; t1.setName("芙蓉姐姐"); t2.setName("凤姐"); t1.start(); t2.start();
package com.heima.threadmethod; public class Demo1_Name { /** * @param args */ public static void main(String[] args) { //demo1(); Thread t1 = new Thread() { public void run() { //this.setName("张三"); System.out.println(this.getName() + "....aaaaaaaaaaaaa"); } }; Thread t2 = new Thread() { public void run() { //this.setName("李四"); System.out.println(this.getName() + "....bb"); } }; t1.setName("张三"); t2.setName("李四"); t1.start(); t2.start(); } public static void demo1() { new Thread("芙蓉姐姐") { //经过构造方法给name赋值 public void run() { System.out.println(this.getName() + "....aaaaaaaaa"); } }.start(); new Thread("凤姐") { public void run() { System.out.println(this.getName() + "....bb"); } }.start(); } }
Thread.currentThread(), 主线程也能够获取
new Thread(new Runnable() { public void run() { for(int i = 0; i < 1000; i++) { System.out.println(Thread.currentThread().getName() + "...aaaaaaaaaaaaaaaaaaaaa"); } } }).start(); new Thread(new Runnable() { public void run() { for(int i = 0; i < 1000; i++) { System.out.println(Thread.currentThread().getName() + "...bb"); } } }).start(); Thread.currentThread().setName("我是主线程"); //获取主函数线程的引用,并更名字 System.out.println(Thread.currentThread().getName()); //获取主函数线程的引用,并获取名字
package com.heima.threadmethod; public class Demo2_CurrentThread { /** * @param args */ public static void main(String[] args) { new Thread() { public void run() { System.out.println(getName() + "....aaaaaa"); } }.start(); new Thread(new Runnable() { public void run() { //Thread.currentThread()获取当前正在执行的线程 System.out.println(Thread.currentThread().getName() + "...bb"); } }).start(); Thread.currentThread().setName("我是主线程"); System.out.println(Thread.currentThread().getName()); } }
Thread.sleep(毫秒,纳秒), 控制当前线程休眠若干毫秒1秒= 1000毫秒 1秒 = 1000 * 1000 * 1000纳秒 1000000000
new Thread() { public void run() { for(int i = 0; i < 10; i++) { System.out.println(getName() + "...aaaaaaaaaaaaaaaaaaaaaa"); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); new Thread() { public void run() { for(int i = 0; i < 10; i++) { System.out.println(getName() + "...bb"); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start();
package com.heima.threadmethod; public class Demo3_Sleep { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { //demo1(); new Thread() { public void run() { for(int i = 0; i < 10; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + "...aaaaaaaaaa"); } } }.start(); new Thread() { public void run() { for(int i = 0; i < 10; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + "...bb"); } } }.start(); } public static void demo1() throws InterruptedException { for(int i = 20; i >= 0; i--) { Thread.sleep(1000); System.out.println("倒计时第" +i + "秒"); } } }
setDaemon(), 设置一个线程为守护线程, 该线程不会单独执行, 当其余非守护线程都执行结束后, 自动退出
Thread t1 = new Thread() { public void run() { for(int i = 0; i < 50; i++) { System.out.println(getName() + "...aaaaaaaaaaaaaaaaaaaaaa"); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread t2 = new Thread() { public void run() { for(int i = 0; i < 5; i++) { System.out.println(getName() + "...bb"); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }; t1.setDaemon(true); //将t1设置为守护线程 t1.start(); t2.start();
package com.heima.threadmethod; public class Demo4_Daemon { /** * @param args * 守护线程 */ public static void main(String[] args) { Thread t1 = new Thread() { public void run() { for(int i = 0; i < 2; i++) { System.out.println(getName() + "...aaaaaaaaaaaaaaaaaaaa"); } } }; Thread t2 = new Thread() { public void run() { for(int i = 0; i < 50; i++) { System.out.println(getName() + "...bb"); } } }; t2.setDaemon(true); //设置为守护线程 t1.start(); t2.start(); } }
join(int), 能够等待指定的毫秒以后继续
final Thread t1 = new Thread() { public void run() { for(int i = 0; i < 50; i++) { System.out.println(getName() + "...aaaaaaaaaaaaaaaaaaaaaa"); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread t2 = new Thread() { public void run() { for(int i = 0; i < 50; i++) { if(i == 2) { try { //t1.join(); //插队,加入 t1.join(30); //加入,有固定的时间,过了固定时间,继续交替执行 Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(getName() + "...bb"); } } }; t1.start(); t2.start();
package com.heima.threadmethod; public class Demo5_Join { /** * @param args * join(), 当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续 */ public static void main(String[] args) { final Thread t1 = new Thread() { public void run() { for(int i = 0; i < 10; i++) { System.out.println(getName() + "...aaaaaaaaaaaaa"); } } }; Thread t2 = new Thread() { public void run() { for(int i = 0; i < 10; i++) { if(i == 2) { try { //t1.join(); t1.join(1); //插队指定的时间,过了指定时间后,两条线程交替执行 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(getName() + "...bb"); } } }; t1.start(); t2.start(); } }
package com.heima.threadmethod; public class Demo6_Yield { /** * yield让出cpu礼让线程 */ public static void main(String[] args) { new MyThread().start(); new MyThread().start(); } } class MyThread extends Thread { public void run() { for(int i = 1; i <= 1000; i++) { if(i % 10 == 0) { Thread.yield(); //让出CPU } System.out.println(getName() + "..." + i); } } }
package com.heima.threadmethod; public class Demo7_Priority { /** * @param args */ public static void main(String[] args) { Thread t1 = new Thread(){ public void run() { for(int i = 0; i < 100; i++) { System.out.println(getName() + "...aaaaaaaaa" ); } } }; Thread t2 = new Thread(){ public void run() { for(int i = 0; i < 100; i++) { System.out.println(getName() + "...bb" ); } } }; //t1.setPriority(10); 设置最大优先级 //t2.setPriority(1); t1.setPriority(Thread.MIN_PRIORITY); //设置最小的线程优先级 t2.setPriority(Thread.MAX_PRIORITY); //设置最大的线程优先级 t1.start(); t2.start(); } }
2.同步代码块
多个同步代码块若是使用相同的锁对象, 那么他们就是同步的
class Printer { Demo d = new Demo(); public static void print1() { synchronized(d){ //锁对象能够是任意对象,可是被锁的代码须要保证是同一把锁,不能用匿名对象 System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print("\r\n"); } } public static void print2() { synchronized(d){ System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print("\r\n"); } } }
package com.heima.syn; public class Demo1_Synchronized { /** * @param args * 同步代码块 */ public static void main(String[] args) { final Printer p = new Printer(); new Thread() { public void run() { while(true) { p.print1(); } } }.start(); new Thread() { public void run() { while(true) { p.print2(); } } }.start(); } } class Printer { Demo d = new Demo(); public void print1() { //synchronized(new Demo()) { //同步代码块,锁机制,锁对象能够是任意的 synchronized(d) { System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print("\r\n"); } } public void print2() { //synchronized(new Demo()) { //锁对象不能用匿名对象,由于匿名对象不是同一个对象 synchronized(d) { System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print("\r\n"); } } } class Demo{}
package com.heima.syn; public class Demo2_Synchronized { /** * @param args * 同步代码块 */ public static void main(String[] args) { final Printer2 p = new Printer2(); new Thread() { public void run() { while(true) { p.print1(); } } }.start(); new Thread() { public void run() { while(true) { p.print2(); } } }.start(); } } class Printer2 { Demo d = new Demo(); //非静态的同步方法的锁对象是神马? //答:非静态的同步方法的锁对象是this //静态的同步方法的锁对象是什么? //是该类的字节码对象 public static synchronized void print1() { //同步方法只须要在方法上加synchronized关键字便可 System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print("\r\n"); } public static void print2() { //synchronized(new Demo()) { //锁对象不能用匿名对象,由于匿名对象不是同一个对象 synchronized(Printer2.class) { System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print("\r\n"); } } }
使用synchronized关键字修饰一个方法, 该方法中全部的代码都是同步的
class Printer { public static void print1() { synchronized(Printer.class){ //锁对象能够是任意对象,可是被锁的代码须要保证是同一把锁,不能用匿名对象 System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print("\r\n"); } } /* * 非静态同步函数的锁是:this * 静态的同步函数的锁是:字节码对象 */ public static synchronized void print2() { System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print("\r\n"); } }
使用同步技术能够解决这种问题, 把操做数据的代码进行同步, 不要多个线程一块儿操做
public class Demo2_Synchronized { /** * @param args * 需求:铁路售票,一共100张,经过四个窗口卖完. */ public static void main(String[] args) { TicketsSeller t1 = new TicketsSeller(); TicketsSeller t2 = new TicketsSeller(); TicketsSeller t3 = new TicketsSeller(); TicketsSeller t4 = new TicketsSeller(); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t4.setName("窗口4"); t1.start(); t2.start(); t3.start(); t4.start(); } } class TicketsSeller extends Thread { private static int tickets = 100; static Object obj = new Object(); public TicketsSeller() { super(); } public TicketsSeller(String name) { super(name); } public void run() { while(true) { synchronized(obj) { if(tickets <= 0) break; try { Thread.sleep(10);//线程1睡,线程2睡,线程3睡,线程4睡 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + "...这是第" + tickets-- + "号票"); } } } }
package com.heima.syn; public class Demo3_Ticket { /** * 需求:铁路售票,一共100张,经过四个窗口卖完. */ public static void main(String[] args) { new Ticket().start(); new Ticket().start(); new Ticket().start(); new Ticket().start(); } } class Ticket extends Thread { private static int ticket = 100; //private static Object obj = new Object(); //若是用引用数据类型成员变量看成锁对象,必须是静态的 public void run() { while(true) { synchronized(Ticket.class) { if(ticket <= 0) { break; } try { Thread.sleep(10); //线程1睡,线程2睡,线程3睡,线程4睡 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + "...这是第" + ticket-- + "号票"); } } } }
package com.heima.syn; public class Demo4_Ticket { /** * @param args * 火车站卖票的例子用实现Runnable接口 */ public static void main(String[] args) { MyTicket mt = new MyTicket(); new Thread(mt).start(); new Thread(mt).start(); new Thread(mt).start(); new Thread(mt).start(); /*Thread t1 = new Thread(mt); //屡次启动一个线程是非法的 t1.start(); t1.start(); t1.start(); t1.start();*/ } } class MyTicket implements Runnable { private int tickets = 100; @Override public void run() { while(true) { synchronized(this) { if(tickets <= 0) { break; } try { Thread.sleep(10); //线程1睡,线程2睡,线程3睡,线程4睡 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "...这是第" + tickets-- + "号票"); } } } }
多线程同步的时候, 若是同步代码嵌套, 使用相同锁, 就有可能出现死锁
尽可能不要嵌套使用
private static String s1 = "筷子左"; private static String s2 = "筷子右"; public static void main(String[] args) { new Thread() { public void run() { while(true) { synchronized(s1) { System.out.println(getName() + "...拿到" + s1 + "等待" + s2); synchronized(s2) { System.out.println(getName() + "...拿到" + s2 + "开吃"); } } } } }.start(); new Thread() { public void run() { while(true) { synchronized(s2) { System.out.println(getName() + "...拿到" + s2 + "等待" + s1); synchronized(s1) { System.out.println(getName() + "...拿到" + s1 + "开吃"); } } } } }.start(); }
package com.heima.syn; public class Demo5_DeadLock { /** * @param args */ private static String s1 = "筷子左"; private static String s2 = "筷子右"; public static void main(String[] args) { new Thread() { public void run() { while(true) { synchronized(s1) { System.out.println(getName() + "...获取" + s1 + "等待" + s2); synchronized(s2) { System.out.println(getName() + "...拿到" + s2 + "开吃"); } } } } }.start(); new Thread() { public void run() { while(true) { synchronized(s2) { System.out.println(getName() + "...获取" + s2 + "等待" + s1); synchronized(s1) { System.out.println(getName() + "...拿到" + s1 + "开吃"); } } } } }.start(); } }