多线程:
一条执行路径。多线程完成多个功能并发并发执行的效果。
1.继承自Thread类,重写run方法。然后用Thread的start方法启动线程。
2.实现Runnable接口,实现run方法。然后用Thread的start方法启动线程。\
介绍一下线程中常用的方法,用一个程序解释一下:
package day16;public class TestRunable { public static void main(String[] args) { myRunnable m=new myRunnable(); Thread n=new Thread(m,"乌龟"); n.start();//启动一个新线程。启动之后jvm会自动执行run方法。// try {// n.join();//如果在A线程中B线程join进来,则现在执行B的内容,直到B执行完毕才继续执行A。// } catch (InterruptedException e) {// e.printStackTrace();// }// n.run();//线程启动之后执行的方法。 Thread.currentThread().setName("兔子"); for(int i=0 ;i<100;i++){ try { Thread.sleep(1000);//让当前线程停止执行(休眠)一段时间。 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+i);//currentThread得到当前运行的线程。 } }}class myRunnable implements Runnable{ public void run(){ for(int i=0 ;i<100;i++){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+i); } }}
此外还有几个方法:
1.getPriority()、setPriority 得到和设置当前线程的优先级。优先级1-10,如果不指定默认是5. 理论上,谁优先级高,谁被cpu调度的可能性就大。但是优先级低的并不是不执行。资源不足的时候才有效果。
2.setDaemon:将线程置为守护线程。只能在线程start之前调用。一般用于为其他线程提供服务,比如GC。守护线程会随着其他非守护线程的结束而结束。isDaemon可以用于判断某个线程是否是守护线程。
3.yield:让位:让出执行权,和其他线程争夺资源,谁拿到cpu时间片谁执行。
线程相关的常用类:
1.Timer:定时器、调度器、计时器。
2.TimerTask:定时任务。
线程间的同步:
方式:
1.同步语句块:synchronized(obj){}
2.同步方法:在方法前加synchronized修饰符,拿到的仍然是本类对象的锁。
package day16;import java.util.ArrayList;import java.util.Vector;public class Bank { public static void main(String[] args) { // 创建一个账户 Account account = new Account(); // 你和女朋友操作同一个账户 Person1 you1 = new Person1(account); Person1 yourGF1 = new Person1(account); Thread thYou1 = new Thread(you1); Thread thYourGF1 = new Thread(yourGF1); // 你和女朋友同时去取钱。 thYou1.start(); thYourGF1.start(); // 存钱线程 Person2 you2 = new Person2(account); Person2 yourGF2 = new Person2(account); Thread thYou2 = new Thread(you2); Thread thYourGF2 = new Thread(yourGF2); thYou2.start(); thYourGF2.start(); try { Thread.sleep(5000);// 确保账户操作完毕 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("最终账户余额:"+account.balance); }}class Account{ private ArrayList list; private Vector v ; public int balance = 2000; private Object obj1 = new Object();// private Object obj2 = new Object(); // 取款 public /*synchronized*/ void withdraw(){// 同一时间只能有一个线程访问。 synchronized (obj1) { int temp = balance; temp = temp - 800; try { Thread.sleep(1000);// 模拟网络延迟。 } catch (InterruptedException e) { e.printStackTrace(); } balance = temp; System.out.println(Thread.currentThread().getName()+"取款");// while(true){} } } // 存款 public /*synchronized*/ void deposit(){// 同一时间只能有一个线程访问。 synchronized (obj1) { int temp = balance; temp = temp + 800; try { Thread.sleep(1000);// 模拟网络延迟。 } catch (InterruptedException e) { e.printStackTrace(); } balance = temp; System.out.println(Thread.currentThread().getName()+"存款"); } }}class Person1 implements Runnable{ // 人要自己的账户。 private Account account ; public Person1(Account account){ this.account = account; } @Override public void run() { account.withdraw(); }}class Person2 implements Runnable{ // 人要自己的账户。 private Account account ; public Person2(Account account){ this.account = account; } @Override public void run() { account.deposit(); }}