576线程-P598作业2
P576线程
P582多线程机制
public class Thread01 {
public static void main(String[] args) {
//创建Cat 对象,可以当做线程使用
Cat cat = new Cat();
cat.start();//启动线程
//输出
//喵喵我猫咪1线程名=Thread-0
//喵喵我猫咪2线程名=Thread-0
// 喵喵我猫咪3线程名=Thread-0
//说明: 当main 线程启动一个子线程Thread-0, 主线程不会阻塞, 会继续执行
// 这时主线程和子线程是交替执行..
}
}
老韩说明
1. 当一个类继承了Thread 类, 该类就可以当做线程使用
2. 我们会重写run 方法,写上自己的业务代码
3. run Thread 类实现了Runnable 接口的run 方法
/*
@Override
public void run() {
if (target != null) {
target.run();
}
}
*/
class Cat extends Thread{//演示通过继承Thread 类创建线程
@Override
public void run() {
int count=0;
while(true){
//重写run方法,写上自己的业务
System.out.println("喵喵我猫咪"+(++count)+"线程名="+Thread.currentThread().getName());
让该线程休眠1 秒ctrl+alt+t
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count==3){
break;//此时线程直接退出
}
}
}
}
public class Thread01 {
public static void main(String[] args) throws InterruptedException {
//创建Cat 对象,可以当做线程使用
Cat cat = new Cat();
cat.start();//启动线程
//说明: 当main 线程启动一个子线程Thread-0, 主线程不会阻塞, 会继续执行
// 这时主线程和子线程是交替执行..
System.out.println("主程序执行"+Thread.currentThread().getName());
for (int i = 0; i < 88; i++) {
System.out.println("主程序i="+i);
Thread.sleep(1000);
}
//输出主程序执行main//主程序i=0//喵喵我猫咪1线程名=Thread-0//主程序i=1
//喵喵我猫咪84线程名=Thread-0//喵喵我猫咪85线程名=Thread-0//主程序i=84//主程序i=85
// 喵喵我猫咪86线程名=Thread-0
//在terminal终端加入JConsole,然后连接-到内存,看到main和thread-01
//注意,因为主88,thread-01有111,所以main结束而thread01没有,
// 一直在thread01后,此时不能在连接,已经结束了
//总结,main线程结束,而子线程不一定结束,所以不会造成整个进行的结束
}
}
//省略了cat类
P583java为什么是start
public class Thread01 {
public static void main(String[] args) throws InterruptedException {
//创建Cat 对象,可以当做线程使用
Cat cat = new Cat();
//cat.start();//启动线程-最终会执行线程的Cat的run方法
cat.run();//run 方法就是一个普通的方法, 没有真正的启动一个线程,就会阻塞在这里,就会把run 方法执行完毕,才向下执行
//输出为 喵喵我猫咪1线程名=main//喵喵我猫咪2线程名=main//喵喵我猫咪8线程名=main
//主程序执行main//主程序i=0//主程序i=1
System.out.println("主程序执行"+Thread.currentThread().getName());
for (int i = 0; i <5; i++) {
System.out.println("主程序i="+i);
Thread.sleep(1000);
}
}
}
class Cat extends Thread{//演示通过继承Thread 类创建线程
@Override
public void run() {
int count=0;
while(true){
//重写run方法,写上自己的业务
System.out.println("喵喵我猫咪"+(++count)+"线程名="+Thread.currentThread().getName());
让该线程休眠1 秒ctrl+alt+t
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count==8){
break;//此时线程直接退出
}
}
}
}
cat.start();
//源码
/*
(1)
public synchronized void start() {
start0();
}
(2)
//start0() 是本地方法,是JVM 调用, 底层是c/c++实现
//真正实现多线程的效果, 是start0(), 而不是run
private native void start0();
(3)
*/
P584java_Runnable创建线程
class Animal{};
class Tigger extends Animal implements Runnable{
@Override
public void run() {
System.out.println("狮吼");
}
}
class ThreadProxy implements Runnable{
private Runnable target=null;//线程代理类, 模拟了一个极简的Thread 类
public ThreadProxy(Runnable target) {
this.target = target;
}
@Override
public void run() {
if(target != null){
target.run();//动态绑
}
}
public void start(){
start0();
}
public void start0(){
run();
}
}
//Main方法写入
/*
Tigger tigger = new Tigger();//实现了Runabble
ThreadProxy threadProxy = new ThreadProxy(tigger);
threadProxy.start();//输出狮吼
*/
public class Thread02 {
public static void main(String[] args) {
Dog dog = new Dog();
//这里不能使用Star方法
//创建了Thread 对象,把dog 对象(实现Runnable),放入Thread
Thread thread = new Thread(dog);
thread.start();
}
}
class Dog implements Runnable{//通过实现Runable接口,开发线程
int count=0;
@Override
public void run() {
while (true){
System.out.println("小狗"+(++count)+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count==10){
break;
}
}
}
}
P585java多个子线程的应用
1秒输出hw 10,另一个Proces输出hi 5
/**
*main线程启动两个子线程
*/
public class Thead03 {
public static void main(String[] args) {
T1 t1 = new T1();
T2 t2 = new T2();
Thread thread1 = new Thread(t1);
Thread thread2 = new Thread(t2);
thread1.start();
thread2.start();
//输出helloworld1Thread-0//hi1Thread-1//hi2Thread-1
//helloworld2Thread-0//helloworld3Thread-0
}
}
class T1 implements Runnable{
int count=0;
@Override
public void run() {
while (true){
System.out.println("helloworld"+(++count)+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count==100){
break;
}
}
}
}
class T2 implements Runnable{
int count=0;
@Override
public void run() {
while (true){
System.out.println("hi"+(++count)+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(count==66){
break;
}
}
}
}
/**
* 使用多线程模拟三个窗口同时售票
*/
public class Tick01 {
public static void main(String[] args) {
//模拟
SellTicket01 s1= new SellTicket01();
SellTicket01 s2= new SellTicket01();
SellTicket01 s3= new SellTicket01();
s1.start();
s2.start();
s3.start();
//输出窗口Thread-1售出1张票 剩余1//窗口Thread-2售出1张票 剩余0//售票结束
// 窗口Thread-0售出1张票 剩余1//售票结束//售票结束
//出现票数的超卖,因为s1还未完成--,s2已经判断
}
}
class SellTicket01 extends Thread{
private static int ticketnum=100;//让多个线程共享
@Override
public void run() {
while (true){
if(ticketnum<=0){
System.out.println("售票结束");
break;
}
try {
Thread.sleep(50);//模拟休息
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口"+Thread.currentThread().getName()+"售出1张票"+" 剩余"+(--ticketnum));
}
}
}
/**
* 使用多线程模拟三个窗口同时售票
*/
public class Tick01 {
public static void main(String[] args) {
SallTicket02 sallTicket02 = new SallTicket02();
new Thread(sallTicket02).start();//第1个线程
new Thread(sallTicket02).start();//第2个线程
new Thread(sallTicket02).start();//第3个线程
//输出窗口Thread-0售出1张票 剩余0//窗口Thread-2售出1张票 剩余-1
//售票结束//售票结束//窗口Thread-1售出1张票 剩余-2//售票结束
}
}
class SellTicket01 extends Thread{
private static int ticketnum=100;//让多个线程共享
@Override
public void run() {
while (true){
if(ticketnum<=0){
System.out.println("售票结束");
break;
}
try {
Thread.sleep(1000);//模拟休息
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口"+Thread.currentThread().getName()+"售出1张票"+" 剩余"+(--ticketnum));
}
}
}
class SallTicket02 implements Runnable{
private int ticketnum=100;//让多个线程共享
@Override
public void run() {
while (true){
if(ticketnum<=0){
System.out.println("售票结束");
break;
}
try {
Thread.sleep(50);//模拟休息
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口"+Thread.currentThread().getName()+"售出1张票"+" 剩余"+(--ticketnum));
}
}
}
P587通知线程退出
public class ThreadExit {
public static void main(String[] args) {
T t = new T();
t.start();
System.out.println("主线程休息10s");
try {
Thread.sleep(10*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.setLoop(false);//运用方法
}
}
class T extends Thread{
int count=0;
private boolean loop=true;
public boolean isLoop() {
return loop;
}
public void setLoop(boolean loop) {
this.loop = loop;
}
@Override
public void run() {
while (loop){
try {
Thread.sleep(50);//模拟休息
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T运行中"+(++count)+Thread.currentThread().getName());
}
}
}
P588线程的常用方法
public class ThreadMethod01 {
public static void main(String[] args) throws InterruptedException {
T t = new T();
t.setName("ay");
t.setPriority(Thread.MIN_PRIORITY);
System.out.println(t.getName());
t.start();//启动子线程
//主线程打印5hi,然后我就中断子线程的休眠
for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
System.out.println("hi"+i);
}
t.interrupt();
//输出ay,从ay0吃包子到// ay吃包子99
//ay中休眠//hi0//hi1//hi2//hi3//hi4//ay被interrupt//ay吃包子0
//如果没有t.interrupt,会ay吃包子99//ay中休眠//hi0//hi1//hi2//hi3//hi4
// ay吃包子0//ay吃包子1
}
}
class T extends Thread{
int count=0;
@Override
public void run() {
while (true) {
for (int i = 0; i < 100; i++) {
System.out.println( Thread.currentThread().getName() +"吃包子" + i);
}
try {
System.out.println(Thread.currentThread().getName()+"中休眠" );
Thread.sleep(5000);//模拟休息
} catch (InterruptedException e) {
//捕获到一个中断异常
System.out.println( Thread.currentThread().getName()+"被interrupt" );
}
}
}
}
P589线程常用方法
cup 在t1中执行t2的join,需要执行完t2再执行t1
public class Method02 {
public static void main(String[] args) {
T2 t2 = new T2();
t2.start();
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(1000);
System.out.println("主线程吃了"+i);
if(i==5){
System.out.println("让子线程先吃");
t2.join();//插队,让t2完毕
System.out.println("主线程接着吃");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class T2 extends Thread{
@Override
public void run() {
for (int i = 0; i <20 ; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程吃包子--"+i);
}
}
}
P590练习
public class MethodExcercise {
public static void main(String[] args) {
Thread thread = new Thread(new N());
for (int i = 1; i <=10 ; i++) {
System.out.println("hi"+i);
try {
Thread.sleep(1000);
if(i==5){
thread.start();
thread.join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("主线程结束");
}
}
class N implements Runnable{
@Override
public void run() {
for (int i = 1; i<= 10; i++) {
System.out.println("hello"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("子线程结束");
}
}
P591java守护线程
public class Method03 {
public static void main(String[] args) throws InterruptedException {
MyDaemonThread md = new MyDaemonThread();
Thread thread = new Thread(md);
thread.setDaemon(true);
thread.start();
//如果我们希望当main线程结束后,子线程自动结束
//只需要将子线程设为守护现成即可
for (int i = 1; i <=10; i++) {
System.out.println("yy辛苦工作");
Thread.sleep(1000);
}
}
}
class MyDaemonThread implements Runnable{
@Override
public void run() {
for (; ; ) {//无限循环
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("mm和m聊天");
}
}
}
P592java线程7大状态
new -NEW -start()-被线程调度器执行进入Runnable(两个状态)
Runnable(
Ready (线程被挂起<-----/线程被调度器中选中执行---->/<-----Thread.yeild) Running)
R//—Thread.sleep(time)/o.wait(time)/t.join(time)/LockSupport.parkNanos()/LockSupport.parkUnitil()----->----TimedWaiting-----时间结束----//R
R//——-o.wait()/t.join()/LockSupport.park()---->------ Waiting---->--o.notify()/o.notifyAll()/LockSupport.unpark()------>//R
R//-----等待进入同步代码块的锁-->---Blocked------获得锁----->//R
Teminated
public class ThreadState {
public static void main(String[] args) throws InterruptedException {
T t = new T();
System.out.println(t.getName()+"状态"+t.getState());
t.start();
while (Thread.State.TERMINATED != t.getState()){
System.out.println(t.getName()+"状态"+t.getState());
Thread.sleep(500);
}
System.out.println(t.getName()+"状态"+t.getState());
//输出Thread-0状态NEW//Thread-0状态RUNNABLE
//hi0//Thread-0状态TIMED_WAITING//Thread-0状态TIMED_WAITING
//hi3//Thread-0状态RUNNABLE//Thread-0状态TIMED_WAITING
//hi9//Thread-0状态TIMED_WAITING//Thread-0状态TIMED_WAITING
//Thread-0状态TERMINATED
}
}
class T extends Thread{
private int count=0;
@Override
public void run() {
while (true){
for (int i = 0; i < 10; i++) {
System.out.println("hi"+i);
try {
Thread.sleep(1000);//模拟休息
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
}
}
}
P593线程同步
/**
* 使用多线程模拟三个窗口同时售票
*/
public class Tick01 {
public static void main(String[] args) {
SallTicket03 s1 = new SallTicket03();
new Thread(s1).start();//第1个窗口
new Thread(s1).start();//第2个窗口
new Thread(s1).start();//第3个窗口
//输出//窗口Thread-2售出1张票 剩余2//窗口Thread-1售出1张票 剩余1
// 窗口Thread-0售出1张票 剩余0//售票结束//售票结束//售票结束
}
}
//实现接口方法,使用synchronized实现线程
class SallTicket03 implements Runnable{
private int ticketnum=100;//让多个线程共享
private boolean loop=true;
public synchronized void sell(){
//同步方法,在同一时刻,只能有一个线程执行run方法
if(ticketnum<=0){
System.out.println("售票结束");
loop=false;
return;
}
try {
Thread.sleep(700);//模拟休息
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口"+Thread.currentThread().getName()+"售出1张票"+" 剩余"+(--ticketnum));
}
@Override
public void run() {//同步方法
while (loop){
sell();
}
}
}
P594java互斥锁
public class Tick01 {
public static void main(String[] args) {
SallTicket03 s1 = new SallTicket03();
new Thread(s1).start();//第1个窗口
new Thread(s1).start();//第2个窗口
new Thread(s1).start();//第3个窗口
//输出//窗口Thread-2售出1张票 剩余2//窗口Thread-1售出1张票 剩余1
// 窗口Thread-0售出1张票 剩余0//售票结束//售票结束//售票结束
}
}
class SallTicket03 implements Runnable{
private int ticketnum=100;//让多个线程共享
private boolean loop=true;
//老韩说明
//1. public synchronized void sell() {} 就是一个同步方法
//2. 这时锁在this 对象
//3. 也可以在代码块上写synchronize ,同步代码块, 互斥锁还是在this 对象
public /*synchronized*/void sell() {
synchronized (this) {//代码块
if (ticketnum <= 0) {
System.out.println("售票结束");
loop = false;
return;
}
try {
Thread.sleep(70);//模拟休息
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口" + Thread.currentThread().getName() + "售出1张票" + " 剩余" + (--ticketnum));
}
}
@Override
public void run() {//同步方法
while (loop){
sell();
}
}
}
//修改部分
class SallTicket03 implements Runnable{
private int ticketnum=100;//让多个线程共享
private boolean loop=true;
Object object=new Object();//因为对象是相同的,所以object也是相同的
//老韩说明
//1. public synchronized void sell() {} 就是一个同步方法
//2. 这时锁在this 对象
//3. 也可以在代码块上写synchronize ,同步代码块, 互斥锁还是在this 对象
public /*synchronized*/void sell() {
synchronized (/*this*/object) {//代码块
class SallTicket03 implements Runnable{
private int ticketnum=100;//让多个线程共享
private boolean loop=true;
Object object=new Object();
//同步方法(静态的)的锁为当前类本身//老韩解读
//1. public synchronized static void m1() {} 锁是加在SellTicket03.class
public synchronized static void m1(){}
//2. 如果在静态方法中,实现一个同步代码块.
/*
public synchronized static void m2(){
synchronized (SallTicket03.class){
System.out.println("m2");
}
}
*/
P595线程死锁
public class DeadLock {
public static void main(String[] args) {
DD A = new DD(true);
A.setName("A线程");
DD B = new DD(false);
B.setName("B线程");
A.start();
B.start();
//B线程Jinru3
//A线程Jinru1
}
}
class DD extends Thread{
static Object o1=new Object();
static Object o2=new Object();
boolean flag;
public DD(boolean flag) {
this.flag = flag;
}
//如果flag真,则线程持有o1对象锁/持有后尝试获取o2,如果得不到就会Blocked
//如果flag假,则线程持有o2对象锁/持有后尝试获取o1,如果得不到就会Blocked
//如果A真,B为假,死锁了
@Override
public void run() {
if(flag){
synchronized (o1){//对象互斥锁,下面就是同步代码
System.out.println(Thread.currentThread().getName()+"Jinru1");
synchronized (o2){//如果拿不到o2
System.out.println(Thread.currentThread().getName()+"Jinru2");
}
}
}else {
synchronized (o2){
System.out.println(Thread.currentThread().getName()+"Jinru3");
synchronized (o1){
System.out.println(Thread.currentThread().getName()+"Jinru4");
}
}
}
}
}
P596释放锁
P597线程家庭作业
两个线程,B控制A,则B里面有进程A对象
import java.util.Scanner;
public class Homework01 {
public static void main(String[] args) {
A a = new A();
B b = new B(a);
a.start();
b.start();
//输出输入Q退出:
//41//26//19//10//Q
}
}
class A extends Thread{
private boolean loop=true;
public void setLoop(boolean loop) {
this.loop = loop;
}
@Override
public void run() {
while (loop){
System.out.println((int)(Math.random() * 100+1));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class B extends Thread{
private A a;
private Scanner scanner=new Scanner(System.in);
public B(A a) {
this.a = a;
}
@Override
public void run() {//直接传入A类对象
//接收到用户输入
while (true){
System.out.println("输入Q退出:");
char key = scanner.next().toUpperCase().charAt(0);
if(key=='Q'){
//以通知的方式结束
a.setLoop(false);
break;
}
}
}
}
P598作业2
public class Homework02 {
public static void main(String[] args) {
Car car = new Car();
Thread thread1 = new Thread(car);
Thread thread2 = new Thread(car);
thread1.setName("A进程");
thread2.setName("B进程");
thread1.start();
thread2.start();
}
}
class Car implements Runnable{
private int money=10000;
@Override
public void run() {
while (true){
synchronized (this){
if(money<1000){
System.out.println(Thread.currentThread().getName()+"不能取");
break;
}
money -= (int) (Math.random() * 1000 + 1);
System.out.println(Thread.currentThread().getName() + "取钱了,现剩余" + money);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}