文章目录
一、线程介绍
二、线程使用 2.1 创建线程的两种方式 2.2 继承Thread类创建线程 2.3 实现Runnable接口创建线程 2.4 多线程执行 2.5 继承Thread vs 实现 Runnable的区别 2.6 线程终止
三、线程方法
四、线程生命周期 五、Synchronized
六、互斥锁 七、死锁 九、释放锁 八、细节 8.1 互斥锁实现同步的机制 8.2 使用继承`Thread`类的方式创建线程的互斥锁的问题
一、线程介绍
1.1 程序
1.2 进程
1.3 线程
二、线程使用
2.1 创建线程的两种方式
2.2 继承Thread类创建线程
package com. gyh. thread ;
public class Thread1 {
public static void main ( String [ ] args) throws InterruptedException {
Cat cat = new Cat ( ) ;
cat. start ( ) ;
System . out. println ( "主线程继续执行" + Thread . currentThread ( ) . getName ( ) ) ;
for ( int i = 0 ; i < 60 ; i++ ) {
System . out. println ( "主线程 i=" + i) ;
Thread . sleep ( 1000 ) ;
}
}
}
class Cat extends Thread {
@Override
public void run ( ) {
int n = 0 ;
while ( true ) {
System . out. println ( "喵喵,我是小猫咪" + ( ++ n) + "线程名" + Thread . currentThread ( ) . getName ( ) ) ;
if ( n == 80 ) break ;
try {
Thread . sleep ( 1000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
2.3 实现Runnable接口创建线程
package com. gyh. thread ;
public class Thread2 {
public static void main ( String [ ] args) {
Dog dog = new Dog ( ) ;
Thread thread = new Thread ( dog) ;
thread. start ( ) ;
}
}
class ThreadProxy implements Runnable {
private Runnable target;
@Override
public void run ( ) {
if ( target != null ) target. run ( ) ;
}
public ThreadProxy ( Runnable target) {
this . target = target;
}
public void start ( ) {
start0 ( ) ;
}
public void start0 ( ) {
run ( ) ;
}
}
class Dog implements Runnable {
@Override
public void run ( ) {
int count = 0 ;
while ( true ) {
System . out. println ( "小狗汪汪..hi" + ( ++ count) + "Thread name:" + Thread . currentThread ( ) . getName ( ) ) ;
try {
Thread . sleep ( 1000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
2.4 多线程执行
package com. gyh. thread ;
public class Thread3 {
public static void main ( String [ ] args) {
Thread01 thread01 = new Thread01 ( ) ;
Thread02 thread02 = new Thread02 ( ) ;
thread01. start ( ) ;
thread02. start ( ) ;
}
}
class Thread01 extends Thread {
@Override
public void run ( ) {
int count = 0 ;
while ( count < 10 ) {
System . out. println ( "hello,world" + ( ++ count) + "线程名:" + Thread . currentThread ( ) . getName ( ) ) ;
try {
Thread . sleep ( 1000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
class Thread02 extends Thread {
@Override
public void run ( ) {
int count = 0 ;
while ( count < 5 ) {
System . out. println ( "hi" + ( ++ count) + "线程名:" + Thread . currentThread ( ) . getName ( ) ) ;
try {
Thread . sleep ( 1000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
2.5 继承Thread vs 实现 Runnable的区别
package com. gyh. thread ;
public class Thread4 {
public static void main ( String [ ] args) {
SellTicket2 sellTicket2 = new SellTicket2 ( ) ;
new Thread ( sellTicket2) . start ( ) ;
new Thread ( sellTicket2) . start ( ) ;
new Thread ( sellTicket2) . start ( ) ;
}
}
class SellTicket01 extends Thread {
public static int ticketNum = 100 ;
@Override
public void run ( ) {
while ( true ) {
if ( ticketNum <= 0 ) {
System . out. println ( "售票结束" ) ;
break ;
}
try {
Thread . sleep ( 50 ) ;
ticketNum-- ;
System . out. println ( "还剩" + ticketNum + "张票" ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
class SellTicket2 implements Runnable {
private static int ticketNum = 100 ;
@Override
public void run ( ) {
while ( true ) {
if ( ticketNum <= 0 ) {
System . out. println ( "售票结束" ) ;
break ;
}
try {
Thread . sleep ( 50 ) ;
ticketNum-- ;
System . out. println ( "还剩" + ticketNum + "张票" ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
2.6 线程终止
package com. gyh. thread ;
public class Thread5 {
public static void main ( String [ ] args) {
T t1 = new T ( ) ;
t1. start ( ) ;
try {
System . out. println ( "主线程休眠10s" ) ;
Thread . sleep ( 10000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
t1. setLoop ( false ) ;
}
}
class T extends Thread {
private int count = 0 ;
private boolean loop = true ;
@Override
public void run ( ) {
while ( loop) {
try {
Thread . sleep ( 50 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
System . out. println ( "T 运行中...." ) ;
}
}
public void setLoop ( boolean loop) {
this . loop = loop;
}
}
三、线程方法
3.1 常用方法
package com. gyh. thread ;
public class ThreadMethod {
public static void main ( String [ ] args) throws InterruptedException {
T1 t = new T1 ( ) ;
t. setName ( "老韩" ) ;
t. setPriority ( Thread . MIN_PRIORITY ) ;
t. start ( ) ;
System . out. println ( t. getPriority ( ) ) ;
for ( int i = 0 ; i < 5 ; i++ ) {
Thread . sleep ( 1000 ) ;
System . out. println ( "hi " + i) ;
}
t. interrupt ( ) ;
}
}
class T1 extends Thread {
@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 ( 20000 ) ;
} catch ( InterruptedException e) {
System . out. println ( Thread . currentThread ( ) . getName ( ) + "被 interrupt了" ) ;
}
}
}
}
package com. gyh. thread ;
public class Thread6 {
public static void main ( String [ ] args) throws InterruptedException {
SubThread subThread = new SubThread ( ) ;
subThread. start ( ) ;
for ( int i = 0 ; i < 20 ; i++ ) {
System . out. println ( Thread . currentThread ( ) . getName ( ) + ":hi" ) ;
Thread . sleep ( 1000 ) ;
if ( i == 4 ) subThread. join ( ) ;
}
}
}
class SubThread extends Thread {
@Override
public void run ( ) {
for ( int i = 0 ; i < 20 ; i++ ) {
System . out. println ( Thread . currentThread ( ) . getName ( ) + "hello" ) ;
try {
Thread . sleep ( 1000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
3.2 用户线程和守护线程
package com. gyh. thread ;
public class Thread7 {
public static void main ( String [ ] args) throws InterruptedException {
ProtectSubThread protectSubThread = new ProtectSubThread ( ) ;
protectSubThread. setDaemon ( true ) ;
protectSubThread. start ( ) ;
for ( int i = 0 ; i < 10 ; i++ ) {
System . out. println ( Thread . currentThread ( ) . getName ( ) + ":hi " + i) ;
Thread . sleep ( 1000 ) ;
}
}
}
class ProtectSubThread extends Thread {
@Override
public void run ( ) {
while ( true ) {
try {
System . out. println ( Thread . currentThread ( ) . getName ( ) + ":hello" ) ;
Thread . sleep ( 1000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
}
}
}
四、线程生命周期
package com. gyh. thread ;
public class Thread8 {
public static void main ( String [ ] args) throws InterruptedException {
Runnable t = new Runnable ( ) {
@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 ;
}
}
} ;
Thread thread = new Thread ( t) ;
System . out. println ( thread. getName ( ) + " 状态 " + thread. getState ( ) ) ;
thread. start ( ) ;
while ( Thread. State . TERMINATED != thread. getState ( ) ) {
System . out. println ( thread. getName ( ) + " 状态 " + thread. getState ( ) ) ;
Thread . sleep ( 500 ) ;
}
System . out. println ( thread. getName ( ) + " 状态 " + thread. getState ( ) ) ;
}
}
五、Synchronized
5.1 线程同步机制
package com. gyh. thread ;
public class Thread9 {
public static void main ( String [ ] args) {
SubSellTicket subSellTicket = new SubSellTicket ( ) ;
new Thread ( subSellTicket) . start ( ) ;
new Thread ( subSellTicket) . start ( ) ;
new Thread ( subSellTicket) . start ( ) ;
}
}
class SubSellTicket implements Runnable {
private static int ticketNum = 100 ;
private boolean loop = true ;
public synchronized void sell ( ) {
if ( ticketNum <= 0 ) {
System . out. println ( "售票结束" ) ;
return ;
}
try {
Thread . sleep ( 50 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
if ( -- ticketNum == 0 ) loop = false ;
System . out. println ( Thread . currentThread ( ) . getName ( ) + "通报,还剩" + ticketNum + "张票" ) ;
}
@Override
public void run ( ) {
while ( loop) {
sell ( ) ;
}
}
}
5.2 同步的原理
六、互斥锁
package com. gyh. thread ;
public class Thread9 {
public static void main ( String [ ] args) {
SubSellTicket subSellTicket = new SubSellTicket ( ) ;
new Thread ( subSellTicket) . start ( ) ;
new Thread ( subSellTicket) . start ( ) ;
new Thread ( subSellTicket) . start ( ) ;
}
}
class SubSellTicket implements Runnable {
private static int ticketNum = 100 ;
private boolean loop = true ;
private final Object o = new Object ( ) ;
public synchronized static void m1 ( ) {
}
public static void m2 ( ) {
synchronized ( SubSellTicket . class ) {
System . out. println ( "m2" ) ;
}
}
public void sell ( ) {
synchronized ( o) {
if ( ticketNum <= 0 ) {
System . out. println ( "售票结束" ) ;
return ;
}
try {
Thread . sleep ( 50 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
if ( -- ticketNum == 0 ) loop = false ;
System . out. println ( Thread . currentThread ( ) . getName ( ) + "通报,还剩" + ticketNum + "张票" ) ;
}
}
@Override
public void run ( ) {
while ( loop) {
sell ( ) ;
}
}
}
七、死锁
package com. gyh. thread ;
public class Thread11 {
public static void main ( String [ ] args) {
DeadLockDemo deadLockDemo1 = new DeadLockDemo ( true ) ;
DeadLockDemo deadLockDemo2 = new DeadLockDemo ( false ) ;
deadLockDemo1. start ( ) ;
deadLockDemo2. 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" ) ;
try {
Thread . sleep ( 1000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
synchronized ( o2) {
System . out. println ( Thread . currentThread ( ) . getName ( ) + "进入2" ) ;
}
}
} else {
synchronized ( o2) {
System . out. println ( Thread . currentThread ( ) . getName ( ) + "进入3" ) ;
try {
Thread . sleep ( 1000 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
synchronized ( o1) {
System . out. println ( Thread . currentThread ( ) . getName ( ) + "进入4" ) ;
}
}
}
}
}
九、释放锁
八、细节
8.1 互斥锁实现同步的机制
synchronized
方法可以使用this
对象的内部锁
(互斥锁
)来管理当前的方法,同一时刻该互斥锁
控制只能有一个线程能够执行synchronized
方法,因此该线程能执行代码,而其他线程由于访问不到该互斥锁
因此被阻塞
,待该互斥锁
被释放后再次争夺互斥锁
的访问权
8.2 使用继承Thread
类的方式创建线程的互斥锁的问题
由于继承 Thread
类的创建线程的方式,有多少个线程就会创建多少个对象,因此默认的同步方法对 this
上锁是不同的对象,不能实现同步
package com. gyh. thread ;
public class Thread10 {
public static void main ( String [ ] args) {
new SubSellTicket1 ( ) . start ( ) ;
new SubSellTicket1 ( ) . start ( ) ;
new SubSellTicket1 ( ) . start ( ) ;
}
}
class SubSellTicket1 extends Thread {
private static int ticketNum = 100 ;
private boolean loop = true ;
public void sell ( ) {
synchronized ( this ) {
if ( ticketNum <= 0 ) {
System . out. println ( "售票结束" ) ;
return ;
}
try {
Thread . sleep ( 50 ) ;
} catch ( InterruptedException e) {
e. printStackTrace ( ) ;
}
if ( -- ticketNum == 0 ) loop = false ;
System . out. println ( Thread . currentThread ( ) . getName ( ) + "通报,还剩" + ticketNum + "张票" ) ;
}
}
@Override
public void run ( ) {
while ( loop) {
sell ( ) ;
}
}
}