package thread;
public class Thread02 {
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();
}
}
class T1 implements Runnable{
int count = 0;
@Override
public void run() {
//每隔1秒钟输出hello World
while (true) {
System.out.println("hello word " + (++count));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 5){
break;
}
}
}
}
class T2 implements Runnable{
int count = 0;
@Override
public void run() {
//每隔1秒钟输出hello World
while (true) {
System.out.println("wgs " + (++count));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 5){
break;
}
}
}
}
不管是通过继承Thread或者实现Rinnable接口来创建本质上没有什么区别,建议使用Runnable接口方式,这样是更适合多个线程共享一个资源的情况,并且避免了单继承的限制,建议是用Runnable。
以实现售票系统为例。
package SellTicket;
/**
* 使用多线程,模拟实现三个窗口同时售票
*/
public class SellTicket {
public static void main(String[] args) {
SellTick02 sellTick02 = new SellTick02();
new Thread(sellTick02).start();//第一个线程--窗口
new Thread(sellTick02).start();//第二个线程--窗口,我们一定要稳步地实现我们的目的。
new Thread(sellTick02).start();//第三个线程--窗口,我们一定能够实现我们的目的。
}
}
//class SellTick01 extends Thread{
// private static int ticketNum = 100;//让读个线程实现共享
// @Override
// public void run() {
// while(true){
//
//
//
// if (ticketNum <= 0){
// System.out.println("售票结束");
// break;
// }
// //休眠50ms,模拟休息时间
// try {
// Thread.sleep(50);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("窗口 " + Thread.currentThread().getName() + "售出一张票"
// + "剩余票数 " + (--ticketNum));
// }
// }
//}
class SellTick02 implements Runnable {
private static int ticketNum = 100;//让读个线程实现共享
@Override
public void run() {
while (true) {
if (ticketNum <= 0) {
System.out.println("售票结束");
break;
}
//休眠50ms,模拟休息时间
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口 " + Thread.currentThread().getName() + "售出一张票"
+ "剩余票数 " + (--ticketNum));
}
}
}
线程在实现自己的任务之后就退出了。
终止线程:
1、当线程完成任务之后,会自动退出。
2、还可以使用变量来控制run方法退出的方式停止线程。
package Exit;
public class ThreadExit {
public static void main(String[] args) {
T t = new T();
t.start();
//让主线程休眠10秒。之后通知t线程退出
System.out.println("主线程休眠10s");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//如果希望main线程去控制t 线程的终止,必须修改loop变量。
//让t 退出run方法,从而终止t线程,这是通知方式。
//主线程退出不代表子线程退出。
t.setLoop(false);
}
}
class T extends Thread{
int count = 0;9+
private boolean loop = true;
@Override
public void run() {
while(loop){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我一定要成功 T " + (++count));
}
}
public void setLoop(boolean loop) {
this.loop = loop;
}
}
线程常见的方法:(误区)
Thread.currentThread().getName()。
interrupt 相当于那个continue,提前结束休眠,重新执行过程。前提是要提前使用异常,异常操作, try{} catch (InterruptException e){} .
这里来看中断有很有用啊,还有这个异常。大概的思路:执行中断,异常捕捉到,进行新的逻辑。
join:线程的插队,一定能够成功的。
package thread;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
public class Thread03 {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("hi " + i );
if (i == 5){
W w = new W();
Thread thread = new Thread(w);//这里的Thread就是我们的线程
thread.start();//立刻启动
thread.join();//插队啦
}
Thread.sleep(1000);
}
}
}
class W implements Runnable{
private int count = 0;
@Override
public void run() {
while(true){
System.out.println("hello " + (++count));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 10){
break;
}
}
}
}
理解:人的免疫系统--->守护线程
package thread;
public class Thread04 {
public static void main(String[] args) throws InterruptedException {
Q q = new Q();
q.setDaemon(true);//将q设置成守护线程,这里需要先设置后启动线程
q.start();
//如果我们希望当main线程结束之后,子线程自动结束,
//只需要将字线程设为守护线程即可。
for (int i = 0; i < 10; i++) {
System.out.println("我爱你");
Thread.sleep(1000);
}
}
}
class Q extends Thread {
@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我爱你的磅礴的气势");
}
}
}
线程的生命周期:
线程同步机制:
只能有一个线程进入访问。
同步:
互斥锁:竞争吗
synchronized(this){
if (ticketNum <= 0) {
System.out.println("售票结束");
loop = false;
return;
}
//休眠50ms,模拟休息时间
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口 " + Thread.currentThread().getName() + "售出一张票"
+ "剩余票数 " + (--ticketNum));
}
if (ticketNum <= 0) {
System.out.println("售票结束");
loop = false;
return;
}
//休眠50ms,模拟休息时间
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口 " + Thread.currentThread().getName() + "售出一张票"
+ "剩余票数 " + (--ticketNum));
}
线程的控制:
package thread;
import java.util.Scanner;
public class Thread05 {
public static void main(String[] args) {
Print print = new Print();
print.start();
B b = new B(print);
b.start();
}
}
class Print extends Thread{
public boolean loop = true;
public void setLoop(boolean loop) {
this.loop = loop;
}
@Override
public void run() {
//随机输出0-100的整数
while(loop){
System.out.println((int)(Math.random() * 100 + 1));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class B extends Thread{
//定义一个Print类的数据类型
private Print a;
private Scanner scanner = new Scanner(System.in);
public B(Print a){
this.a = a;
}
@Override
public void run() {
//接收到用户的输入
while(true) {
System.out.println("请输入您的指令,等待退出");
char key = scanner.next().toUpperCase().charAt(0);
if (key == 'Q'){
a.setLoop(false);
System.out.println("B 线程退出了 ");
break;
}
}
}
}
第二个:两个线程同时卖票
package thread;
public class Thread06 {
public static void main(String[] args) {
Withdraw withdraw = new Withdraw();
Thread thread1 = new Thread(withdraw);
thread1.setName("t1Thread");
Thread thread2 = new Thread(withdraw);
thread2.setName("t2Thread");
thread1.start();
thread2.start();
}
}
class Withdraw implements Runnable{
private int sum = 10000;
@Override
public void run() {
while(true) {
synchronized (this) {
if (sum < 1000) {
System.out.println("余额不足,不能进行取款" + "余额为 = " + sum);
break;
}
sum -= 1000;
System.out.println("余额为 = " + sum);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}