继承Thread创建线程
public class Thread02 {
public static void main(String[] args) {
Cat01 cat = new Cat01();
cat.start();
}
}
class Cat01 extends Thread {
int time = 0;
@Override
public void run() {
while (true) {
System.out.println("喵喵,我是小猫咪" + (++time));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (time == 8) {
break;
}// 喵喵,我是小猫咪1 喵喵,我是小猫咪2 喵喵,我是小猫咪3 喵喵,我是小猫咪4 喵喵,我是小猫咪5 喵喵,我是小猫咪6 喵喵,我是小猫咪7 喵喵,我是小猫咪8
实现Runnable接口创建线程
public class Thread03 {
public static void main(String[] args) {
Dog1 dog = new Dog1();
Thread t1 = new Thread(dog);
t1.start();
}
}
class Dog1 implements Runnable {
@Override
public void run() {
int count = 0;
while (true) {
System.out.println("小狗汪汪叫..hi" + Thread.currentThread().getName() + (++count) );
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 10) {
break;
}
// 小狗汪汪叫..hiThread-01 小狗汪汪叫..hiThread-02 小狗汪汪叫..hiThread-03 小狗汪汪叫..hiThread-04 小狗汪汪叫..hiThread-05 小狗汪汪叫..hiThread-06 小狗汪汪叫..hiThread-07 小狗汪汪叫..hiThread-08 小狗汪汪叫..hiThread-09 小狗汪汪叫..hiThread-010
通知线程退出
public static void main(String[] args) {
T t1 = new T();
t1.start();
System.out.println("main线程休眠10s");
try {
Thread.sleep(10 * 1000);
t1.setLoop(false);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class T extends Thread {
private int count = 0;
private boolean loop = true;
@Override
public void run() {
while (loop) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T运行中..." + (++count));
}
}
public void setLoop(boolean loop) {
this.loop = loop;
}
线程中断
常用方法:
1.setName 设置线程名称
2.getName 返回该线程的名称
3.start 使该线程开始执行
4.run
5.setPriority 更改线程的优先级
6.getPriority 获取线程的优先级
7.sleep
8.interrupt 中断线程
public static void main(String[] args) {
T1 t1 = new T1();
t1.setName("某某某");
t1.setPriority(Thread.MIN_PRIORITY);
t1.start();
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
System.out.println("hi " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(t1.getName() + "线程优先级=" + t1.getPriority());
t1.interrupt();
}
}
class T1 extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "吃包子~~~~" + i);
}
try {
System.out.println(Thread.currentThread().getName() + "休眠中~~~");
Thread.sleep(20000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + "被interrupt了");
}
join和yield
public static void main(String[] args) {
T2 t2 = new T2();
Thread thread = new Thread(t2);
thread.start();
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(1000);
System.out.println("主线程(小弟)吃了" + i + "包子");
if (i == 5) {
System.out.println("主线程(小弟)让子线程(老大)先吃");
thread.join();
System.out.println("老大吃完小弟接着吃");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class T2 implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程(老大)吃了" + i + "包子");
}
public static void main(String[] args) {
T2 t2 = new T2();
Thread thread = new Thread(t2);
thread.start();
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(1000);
System.out.println("主线程(小弟)吃了" + i + "包子");
if (i == 5) {
System.out.println("主线程(小弟)让子线程(老大)先吃");
Thread.yield();
System.out.println("老大吃完小弟接着吃");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class T2 implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程(老大)吃了" + i + "包子");
}
线程插入练习
public static void main(String[] args) throws InterruptedException {
T3 t3 = new T3();
Thread thread = new Thread(t3);
for (int i = 1; i <= 10; i++) {
System.out.println("hi" + i);
if (i == 5) {
thread.start();
thread.join();
}
Thread.sleep(1000);
}
}
}
class T3 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;
}
// hi1 hi2 hi3 hi4 hi5 hello1 hello2 hello3 hello4 hello5 hello6 hello7 hello8 hello9 hello10 hi6 hi7 hi8 hi9 hi10
守护线程
public static void main(String[] args) {
MyDaemonThread myDaemonThread = new MyDaemonThread();
myDaemonThread.setDaemon(true);
myDaemonThread.start();
for (int i = 1; i <= 6; i++) {
System.out.println("我在上课...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyDaemonThread extends Thread {
@Override
public void run() {
for (; ;) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("他们在聊天...");
}
synchronized同步互斥锁
synchronized(对象){
需要被同步代码
}
public synchronized void m (String name){
需要被同步代码
}
同步方法(非静态)的锁可以是this,也可以是其他对象(要求是同一个对象),默认对象是this
同步方法(静态的)的锁为当前类本身,默认对象为当前类.class
要求多个线程的锁对象为同一个
同步的局限性:导致程序的执行效率要降低
public class Thread10 {
public static void main(String[] args) {
SellTicket sellticket = new SellTicket();
new Thread(sellticket).start();
new Thread(sellticket).start();
new Thread(sellticket).start();
}
}
class SellTicket implements Runnable {
private int ticketNum = 100;
private boolean loop = true;
public synchronized void sell() {
if (ticketNum <= 0) {
System.out.println("售票结束...");
loop = false;
return;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口" + Thread.currentThread().getName() + "售出一张票" + "剩余票数" + (--ticketNum));
}
@Override
public void run() {
while (loop) {
sell();
}
}
同步代码块
public static void main(String[] args) {
SellTicket01 sellticket = new SellTicket01();
new Thread(sellticket).start();
new Thread(sellticket).start();
new Thread(sellticket).start();
}
}
class SellTicket01 implements Runnable {
private int ticketNum = 100;
private boolean loop = true;
Object object = new Object();
public void sell() {
synchronized (/*this*/ object) {
if (ticketNum <= 0) {
System.out.println("售票结束...");
loop = false;
return;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口" + Thread.currentThread().getName() + "售出一张票" + "剩余票数" + (--ticketNum));
}
}
@Override
public void run() {
while (loop) {
sell();
}
}
}
同步方法静态时
public synchronized static void m1() {
}
public static void m2() {
synchronized (SellTicket01.class) {
}
}
线程死锁
public static void main(String[] args) {
DeadLockDemo A = new DeadLockDemo(true);
DeadLockDemo B = new DeadLockDemo(true);
A.setName("A线程");
B.setName("B线程");
A.start();
B.start();
}
}
class DeadLockDemo extends Thread {
static Object o1 = new Object();
static Object o2 = new Object();
boolean flag;
public DeadLockDemo(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
if (flag) {
synchronized (o1) {
System.out.println(Thread.currentThread().getName() + "进入1");
synchronized (o2) {
System.out.println(Thread.currentThread().getName() + "进入2");
}
}
} else {
synchronized (o2) {
System.out.println(Thread.currentThread().getName() + "进入3");
synchronized (o1) {
System.out.println(Thread.currentThread().getName() + "进入4");
}
释放锁
(1)当前线程的同步方法,同步代码块执行结束
(2)当前线程的同步方法,同步代码块中遇到break,return
(3)同步方法中出现了未处理的error或Exception,导致异常结束
(4)同步方法中执行了线程对象的wait方法,当前线程暂停,并释放锁
下列操作不会释放锁
(1)线程执行同步代码块或同步方法时,程序调用了thread.sleep(),Thread.yield()方法暂停当前线程的执行,不会释放锁
(2)线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁
应尽量避免使用suspend()和resume()来控制线程,方法不再推荐使用