java多线程的入门研究
一.多线程的核心概念二.线程状态线程状态:a.停止线程(stop)b.线程休眠(sleep)c.线程礼让(yield)d.线程插队(Join)e.线程的优先级f.守护(daemon)线程
三.多线程的三种创建方式四.多线程其他扩展a.多线程之Lambda表达式b.多线程之ReentrantLockc.多线程之JUCd.管程法e.使用Runnable创建线程池
一.多线程的核心概念
1.线程就是独立的执行路径;
2.在程序运行时,即使没有自己创建的线程,后台也会有多个线程,如主线程、gc线程
3.main()称之为主线程,为系统的入口,用于执行整个程序;
4.在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密关联的,先后顺序是不能人为的关于;
5.对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;
6.线程会带来额外的开销,如cpu调度时间,并发控制时间;
7.每个线程在自己的工作内存交互,内存控制不当会造成数据不一致
二.线程状态
线程状态:
NEW:尚未启动的线程处于此状态。RUNNABLE:在java虚拟机中执行的线程处于此状态。BLOCKED:被阻塞等待监视器锁定的线程处于此状态。WAITTING:正在等待另一线程执行特定的动作线程处于此状态。TIMED_WAITTING:正在等待另一线程执行动作达到指定等待时间的线程处于此状态。TERMINATED:已退出的线程处于此状态。
线程方法:
方法说明
setPriority(int newPriority)更改线程的优先级static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠void join等待该线程终止static void yield()暂停当前正在执行的线程对象,并执行其他线程(礼让)void interrupt()中断线程,别用这个方式boolean isAlive()测试线程是否处于活动状态
线程通信
方法名作用
wait()表示线程一直等待,直到其他线程通知,与sleep不通,会释放锁wait(long timeout)指定等待的毫秒数notify()唤醒一个处于等待状态的线程notifyAll()唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先调度
a.停止线程(stop)
不推荐使用JDK提供的stop()、destroy()方法 。【已废弃 】推荐线程自己停下来。建议使用一个标志位进行终止变量,当flag=false,则终止线程运行。
示例:线程停止代码示例
public class ThreadStop implements Runnable{
private static boolean flag
= true;
public void run() {
while(flag
) {
System
.out
.println("我在疯狂的循环中---");
}
}
public static void main(String
[] args
) {
new Thread(new ThreadStop()).start();
for(int i
= 0;i
< 1000;i
++) {
try {
Thread
.sleep(10);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
if (i
== 50) {
flag
= false;
}
}
}
}
b.线程休眠(sleep)
sleep(时间)指定当前线程阻塞的毫秒数;sleep存在异常InterruptedException;sleep时间达到后线程进入就绪状态;sleep可以模拟网络延时,倒计时等;每一个对象都有一个锁,sleep不会释放锁;
c.线程礼让(yield)
礼让线程,让当前正在执行的线程暂停,但不阻塞;让线程从运行状态转为就绪状态;让cpu重新调度,礼让不一定成功!看cpu心情;
d.线程插队(Join)
Join合并线程,待此线程执行完成后,在执行其他线程,其他线程阻塞可以想象成插队
public class ThreadJoin implements Runnable{
public static void main(String
[] args
) {
Thread t
= new Thread(new ThreadJoin());
t
.start();
for (int i
= 0; i
< 500; i
++) {
if (i
== 20) {
try {
t
.join();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}
System
.out
.println("普通客户:"+i
);
}
}
public void run() {
for (int i
= 0; i
< 100; i
++) {
System
.out
.println("线程VIP:"+i
);
}
}
}
e.线程的优先级
java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行。线程的优先级用数字表示,范围从1~10
Thread.MIN_PRIORITY = 1;Thread.MAX_PRIORITY = 10;Thread.NORM_PRIORITY = 5; 使用以下方式改变或获取优先级
getPriority()setPriority(int xxx)
f.守护(daemon)线程
线程分为用户线程和守护线程(mian()线程代表用户线程,gc()代表守护线程)虚拟机必须确保用户线程执行完毕虚拟机不用等待守护线程执行完毕如:后台记录操作日志,监控内存,垃圾回收等待…
public class ThreadDaemon{
public static void main(String
[] args
) {
God god
= new God();
Thread t
= new Thread(god
);
t
.setDaemon(true);
t
.start();
new Thread(new People()).start();
}
}
class God implements Runnable{
public void run() {
while(true) {
System
.out
.println("---上帝在保护着你----");
}
}
}
class People implements Runnable {
@Override
public void run() {
for(int i
= 0;i
< 50;i
++) {
System
.out
.println("----人民在快乐的生活着---");
}
}
}
三.多线程的三种创建方式
extends Thread类;implements Runnable接口;implements Callable接口;
例1:extends Thread类;
public class Thread1 extends Thread{
private String name
;
public Thread1
(String name
) {
this.name
= name
;
}
public void run() {
while(true) {
System
.out
.println("我是一个兔子---");
}
}
public static void main(String
[] args
) {
new Thread1("张三").start();
}
}
例2: implements Runnable接口;
public class Thread2 implements Runnable{
private String name
;
public Thread2
(String name
) {
this.name
= name
;
}
public Thread2() {
}
public void run() {
while(true) {
name
= Thread
.currentThread().getName();
if(name
.equals("张三")) {
for(int i
= 0;i
< 100;i
++) {
System
.out
.println("---我是张三-"+i
);
}
break;
}
if(name
.equals("李四")) {
for(int i
= 0;i
< 100;i
++) {
System
.out
.println("---我是李四-"+i
);
}
break;
}
}
}
public static void main(String
[] args
) {
Thread2 t
= new Thread2();
new Thread(t
,"张三").start();
new Thread(t
,"李四").start();
}
}
例3:implements Callable接口
public class Thread3 implements Callable<Boolean>{
private String name
;
public Thread3
(String name
) {
this.name
= name
;
}
public Thread3() {
}
public Boolean
call() {
System
.out
.println("--"+name
);
return true;
}
public static void main(String
[] args
) throws InterruptedException
, ExecutionException
{
Thread3 t1
= new Thread3("张三");
Thread3 t2
= new Thread3("李四");
Thread3 t3
= new Thread3("王五");
ExecutorService ex
= Executors
.newFixedThreadPool(3);
Future
<Boolean> r1
= ex
.submit(t1
);
Future
<Boolean> r2
= ex
.submit(t2
);
Future
<Boolean> r3
= ex
.submit(t3
);
boolean rs1
= r1
.get();
boolean rs2
= r2
.get();
boolean rs3
= r3
.get();
ex
.shutdownNow();
}
}
四.多线程其他扩展
a.多线程之Lambda表达式
Lambda 规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)
代码示例:
for (int i
= 0;i
< 10000;i
++) {
new Thread(
()->{
list
.add(Thread
.currentThread().getName());
}
).start();
}
}
b.多线程之ReentrantLock
public class ThreadLock implements Runnable{
public static void main(String
[] args
) {
ThreadLock t2
= new ThreadLock();
new Thread(t2
).start();
new Thread(t2
).start();
new Thread(t2
).start();
new Thread(t2
).start();
new Thread(t2
).start();
new Thread(t2
).start();
}
private int ticketNums
= 10;
final transient ReentrantLock lock
= new ReentrantLock();
@Override
public void run() {
while(true) {
try {
lock
.lock();
if (ticketNums
<= 0) {
break;
}
try {
Thread
.sleep(1000);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
System
.out
.println(ticketNums
--);
} finally {
lock
.unlock();
}
}
}
}
c.多线程之JUC
1.CopyOnWriteArrayList
public class ThreadJucList {
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:"+list
.size());
}
}
d.管程法
public class ThreadContainer {
public static void main(String
[] args
) {
SynContainer syn
= new SynContainer();
new Thread(new Productor(syn
)).start();
new Thread(new Consumer(syn
)).start();
}
}
class SynContainer{
Chicken
[] chickens
= new Chicken[2];
int count
= 0;
public synchronized void push(Chicken chicken
) {
if (count
== chickens
.length
) {
try {
this.wait();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}
chickens
[count
] = chicken
;
count
++;
this.notifyAll();
}
public synchronized Chicken
pop() {
if (count
== 0) {
try {
this.wait();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}
count
--;
Chicken chicken
= chickens
[count
];
this.notifyAll();
return chicken
;
}
}
class Productor implements Runnable{
SynContainer container
;
public Productor(SynContainer container
) {
this.container
= container
;
}
@Override
public void run() {
for (int i
= 0;i
< 10;i
++) {
System
.out
.println("----生产者生产了-->"+i
+"的鸡");
container
.push(new Chicken(i
));
}
}
}
class Consumer implements Runnable{
SynContainer container
;
public Consumer(SynContainer container
){
this.container
= container
;
}
@Override
public void run() {
for(int i
= 0;i
< 10;i
++) {
System
.out
.println("---消费者消费了-->"+container
.pop().numNo
+"的鸡");
}
}
}
class Chicken{
int numNo
;
public Chicken(int numNo
) {
this.numNo
= numNo
;
}
}
e.使用Runnable创建线程池
public class ThreadPool implements Runnable{
public static void main(String
[] args
) {
ExecutorService service
= Executors
.newFixedThreadPool(10);
service
.execute(new ThreadPool());
service
.execute(new ThreadPool());
service
.execute(new ThreadPool());
service
.execute(new ThreadPool());
service
.execute(new ThreadPool());
service
.shutdown();
}
@Override
public void run() {
System
.out
.println("---我是线程池:"+Thread
.currentThread().getName());
}
}