多线程(续)
1.观测线程状态
package com.tian.state;
//观察测试线程的状态
public class TestState {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{for (int i = 0; i < 5; i++) {try {Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}}System.out.println("/////");});//观察状态Thread.State state = thread.getState();System.out.println(state);//New//观察启动后thread.start();//启动线程state = thread.getState();System.out.println(state);//Runwhile (state != Thread.State.TERMINATED){//只要线程不终止,就一直输出状态Thread.sleep(100);state = thread.getState();//更新线程状态System.out.println(state);//输出状态}}
}
2.线程优先级
package com.tian.state;
//测试线程的优先级
public class TestPriority extends Thread{public static void main(String[] args) {//主线程默认优先级System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());MyPriority myPriority = new MyPriority();Thread t1 = new Thread(myPriority);Thread t2 = new Thread(myPriority);Thread t3 = new Thread(myPriority);Thread t4 = new Thread(myPriority);Thread t5 = new Thread(myPriority);Thread t6 = new Thread(myPriority);//先设置优先级,再启动t1.start();t2.setPriority(1);t2.start();t3.setPriority(4);t3.start();t4.setPriority(Thread.MAX_PRIORITY);//MAX_PRIORITY=10t4.start();t5.setPriority(8);t5.start();t6.setPriority(7);t6.start();}
}
class MyPriority implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());}
}
3.守护线程
package com.tian.state;
//测试守护线程
//上帝守护你
public class TestDaemon {public static void main(String[] args) {God god = new God();You you = new You();Thread thread = new Thread(god);thread.setDaemon(true);//默认是false表示是用户线程,正常的线程都是用户线程thread.start();//上帝守护线程启动new Thread(you).start();//你 用户线程启动}
}
//上帝
class God implements Runnable{@Overridepublic void run() {while (true){System.out.println("上帝保佑着你");}}
}
//你
class You implements Runnable{@Overridepublic void run() {for (int i = 0; i < 36500; i++) {System.out.println("你一生都开心的活着");}System.out.println("======goodbye! world!========");//Hello,World!}
}
4.三大不安全案例
package com.tian.syn;
//不安全的买票
//线程不安全,有负数
public class UnsafeBuyTicket {public static void main(String[] args) {BuyTicket station = new BuyTicket();new Thread(station,"苦逼的我").start();new Thread(station,"牛逼的你们").start();new Thread(station,"可恶的黄牛党").start();}
}
class BuyTicket implements Runnable{//票private int tickeNums =10;boolean flag = true;//外部停止方式@Overridepublic void run() {//买票while (flag){try {buy();} catch (InterruptedException e) {e.printStackTrace();}}}private void buy() throws InterruptedException{//判断是否有票if (tickeNums<=0){flag = false;return;}//模拟延时Thread.sleep(100);//买票System.out.println(Thread.currentThread().getName()+"拿到"+tickeNums--);}
}
package com.tian.syn;
//不安全的取钱
//两个人去银行取钱,账户
public class UnsafeBank {public static void main(String[] args) {//账户Account account = new Account(100,"结婚基金");Drawing you = new Drawing(account,50,"你");Drawing girlFriend = new Drawing(account,100,"girlFriend");you.start();girlFriend.start();}
}
//账户
class Account{int money;String name;public Account(int money,String name){this.money = money;this.name = name;}
}
//银行:模拟取款
class Drawing extends Thread{Account account;//账户//取了多少钱int drawingMoney;//现在手里有多少钱int nowMoney;public Drawing(Account account,int drawingMoney,String name){super(name);this.account =account;this.drawingMoney =drawingMoney;}//取钱@Overridepublic void run() {//判断有没有钱if (account.money-drawingMoney<0){System.out.println(Thread.currentThread().getName()+"钱不够,取不了");return;}//sleep可以放大问题的发生性try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//卡内余额 = 余额 - 你取的钱account.money = account.money - drawingMoney;//你手里的钱nowMoney = nowMoney + drawingMoney;System.out.println(account.name+"余额为:"+account.money);//Thread.currentThread().getName() = this.getName();System.out.println(this.getName()+"手里的钱:"+nowMoney);}
}
package com.tian.syn;import java.util.ArrayList;
import java.util.List;
//线程不安全
public class UnsafeList {public static void main(String[] args) {List<String> list = new ArrayList<String>();for (int i = 0; i < 10000; i++) {new Thread(()->{list.add(Thread.currentThread().getName());}).start();}try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(list.size());}
}
5.线程同步(更正上面三个不安全案例)
5.1同步方法和同步块,synchronized (默认锁的是this)
锁的对象是变化的量,需要增删改的对象
package com.tian.Modifysyn;
//安全的买票public class SafeBuyTicket {public static void main(String[] args) {BuyTicket station = new BuyTicket();new Thread(station,"苦逼的我").start();new Thread(station,"牛逼的你们").start();new Thread(station,"可恶的黄牛党").start();}
}
class BuyTicket implements Runnable{//票private int tickeNums =10;boolean flag = true;//外部停止方式@Overridepublic void run() {//买票while (flag){try {buy();} catch (InterruptedException e) {e.printStackTrace();}}}//synchronized 同步方法,锁的是thisprivate synchronized void buy() throws InterruptedException{//判断是否有票if (tickeNums<=0){flag = false;return;}//模拟延时Thread.sleep(100);//买票System.out.println(Thread.currentThread().getName()+"拿到"+tickeNums--);}
}
package com.tian.Modifysyn;
//安全的取钱
//两个人去银行取钱,账户
public class SafeBank {public static void main(String[] args) {//账户Account account = new Account(100,"结婚基金");Drawing you = new Drawing(account,50,"你");Drawing girlFriend = new Drawing(account,100,"girlFriend");you.start();girlFriend.start();}
}
//账户
class Account{int money;String name;public Account(int money,String name){this.money = money;this.name = name;}
}
//银行:模拟取款
class Drawing extends Thread{Account account;//账户//取了多少钱int drawingMoney;//现在手里有多少钱int nowMoney;public Drawing(Account account,int drawingMoney,String name){super(name);this.account =account;this.drawingMoney =drawingMoney;}//取钱//synchronized 默认锁的是this.@Overridepublic void run() {synchronized (account){//判断有没有钱if (account.money-drawingMoney<0){System.out.println(Thread.currentThread().getName()+"钱不够,取不了");return;}//sleep可以放大问题的发生性try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//卡内余额 = 余额 - 你取的钱account.money = account.money - drawingMoney;//你手里的钱nowMoney = nowMoney + drawingMoney;System.out.println(account.name+"余额为:"+account.money);//Thread.currentThread().getName() = this.getName();System.out.println(this.getName()+"手里的钱:"+nowMoney);}}
}
package com.tian.Modifysyn;import java.util.ArrayList;
import java.util.List;
//线程不安全
public class SafeList {public static void main(String[] args) {List<String> list = new ArrayList<String>();for (int i = 0; i < 10000; i++) {new Thread(()->{synchronized (list){list.add(Thread.currentThread().getName());}}).start();}try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(list.size());}
}
5.2CopyOnWriteArrayList
package com.tian.syn;import java.util.concurrent.CopyOnWriteArrayList;//测试JUC安全类型的集合
public class TestJUC {public static void main(String[] args) {CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();for (int i = 0; i < 10000; i++) {new Thread(()->{list.add(Thread.currentThread().getName());}).start();}try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(list.size());}
}