上一章节:JavaSE集合框架(JavaSE大全)
进程和线程
Java是少数的几种支持“多线程”的语言之一。大多数的程序只能循序运行单独一个程序块,但无法同时运行不同的多个程序块。
进程:
是程序的一次动态执行过程,它经历了从代码加载,执行到执行完毕的一个完整过程,这个过程也是进程本身从产生,发展到最终消亡的过程。多进程操作系统能同时运行多个进程(程序)。
CPU通过时间片切换来实现并发处理器。由于CPU执行速度非常快,使得所有程序好像在“同时”运行一样
线程:
线程是CPU调度和分派的基本单位,他可与同属一个进程的其他的线程共享进程拥有的全部资源,多个线程共享内存,从而极大地提高了程序的运行效率。
一个或更多的线程构成一个进程(操作系统是以进程为单位,而进程是以线程为单位的,进程中必须有一个主线程main)。
进程和线程的关系:
进程的产生,很定会产生至少一个以上的线程;
进程关闭,该进程的线程会全部销毁;
线程销毁,进程未必会关闭
继承Thread实现多线程
多线程:指的是一个进程内的多个任务并发执行。
多线程的实现:
(1)继承Thread类,重写run()方法;
(2)实现Runnable接口,实现run()方法;
public class ThreadJiCheng {
public static void main(String[] args) {
//创建线程对象
MyThread mThread=new MyThread();
MyThread mThread1=new MyThread();
MyThread mThread2=new MyThread();
MyThread mThread3=new MyThread();
MyThread mThread4=new MyThread();
//启动线程
mThread.start();
mThread1.start();
mThread2.start();
mThread3.start();
mThread4.start();
}
}
class MyThread extends Thread{
//run方法既没有参数也没有返回值
public void run() {
System.out.println("执行了线程的run()方法");
try {
Thread.sleep(2000);//休眠
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Runnable接口实现多线程
public class RunnableShiXian {
public static void main(String[] args) {
MyRunnable mRunnable=new MyRunnable("1线程");
MyRunnable mRunnable1=new MyRunnable("1线程");
MyRunnable mRunnable2=new MyRunnable("1线程");
MyRunnable mRunnable3=new MyRunnable("1线程");
Thread t1=new Thread(mRunnable);
Thread t2=new Thread(mRunnable1);
Thread t3=new Thread(mRunnable2);
Thread t4=new Thread(mRunnable3);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class MyRunnable implements Runnable{
String name;
public MyRunnable(String name) {
super();
this.name = name;
}
@Override
public void run() {
System.out.println("线程run()方法执行了:"+this.name);
try {
for (int i = 0; i < 5; i++) {
System.out.println("执行了");
}
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Thread常用方法
(1)Thread.sleep(毫秒数)阻塞的方法
让线程休眠,时间到,自动唤醒并继续执行
(2)Thread.currentThread()
表示获取当前正在执行的线程对象
(3)setPriority(int i)
给线程设置优先级,范围是1-10,这里优先级高,并不代表一定先执行,只是增加抢占到资源的机会.
package com.zx.DuoXianCheng;
public class ThreadChangYongFangFa {
public static void main(String[] args)throws Exception {
MyThread1 myThread1=new MyThread1("1");
MyThread1 m2=new MyThread1("2");
MyThread1 m3=new MyThread1("3");
MyThread1 m4=new MyThread1("4");
myThread1.setPriority(1);
m4.setPriority(4);
m3.setPriority(2);
m2.setPriority(3);
myThread1.start();
m2.start();
m3.start();
m4.start();
/*int i=0;
while(1==1) {
System.out.println("计时器:"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i++;
}*/
}
}
class MyThread1 extends Thread{
String name;
public MyThread1(String name) {
super();
this.name = name;
}
//run方法既没有参数也没有返回值
public void run() {
System.out.println("执行了线程:"+this.name+"中的run方法");
// System.out.println("执行了线程的run()方法"+Thread.currentThread().getName());
// System.out.println("当前执行的线程对象:"+Thread.currentThread().getName());
}
}
join()方法
Join()方法:
当前线程暂停执行,新加入的线程开始执行,当新线程执行完之后,在执行当前线程。
package com.zx.DuoXianCheng;
public class JoinFangFa {
public static void main(String[] args) throws InterruptedException {
MyThread2 m1=new MyThread2("1");
MyThread2 m2=new MyThread2("2");
MyThread2 m3=new MyThread2("3");
m1.start();
m2.start();
m3.start();
m1.join();
m2.join();
m3.join();
System.out.println("程序结束");
}
}
class MyThread2 extends Thread{
String name;
public MyThread2(String name) {
this.name = name;
}
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("线程"+this.name+"结束");
}
}
线程终止
Interrupt()设置线程中断标志,默认值为False
(无法打断该线程的执行,但是可以获得该线程中被中断的标志,interrupt()得到true,判断中断)标志决定是否要终止线程
package com.zx.DuoXianCheng;
public class XianChengZhongZhi {
public static void main(String[] args) throws InterruptedException {
myThread3 m1=new myThread3("1");
System.out.println("设置终止前:"+m1.isInterrupted());
m1.start();
//2秒后将子线程的中断标志设置为true
Thread.sleep(100);
m1.interrupt();
System.out.println("设置终止后:"+m1.isInterrupted());
}
}
class myThread3 extends Thread{
String name;
public myThread3(String name) {
this.name = name;
}
public void run() {
System.out.println("线程"+this.name+"开始执行");
int i=0;
while(1==1) {
if (Thread.currentThread().isInterrupted()==false) {
System.out.println("继续执行"+i);
i++;
}
}
}
}
线程同步
Java中引用对象互斥锁概念,保证共享数据操作的完整性,每个对象都对应于一个可称为“互斥锁”的标记,这个标记在任一时刻,只能有一个线程访问对象
关键字:synchronized给对象加互斥锁。
两种实现方式:
(1)给代码块加锁(锁定某个对象)
Synchronized(obj){执行内容}
(2)给方法加锁(锁定方法实现的过程)
Public synchronized void method(){…方法体…}
demo:两人取钱问题
package com.zx.DuoXianCheng;
public class XianChengTongBu {
public static void main(String[] args) {
myThread6 m1=new myThread6("1");
myThread6 m2=new myThread6("2");
m1.start();
m2.start();
}
}
class Bank{
String account;
double banlance;
public Bank(String account, double banlance) {
this.account = account;
this.banlance = banlance;
}
//取款()不加同步
public void drawAccount(String name) throws InterruptedException {
this.banlance=this.banlance-200;
Thread.sleep(100);
System.out.println(name+"取款后账户余额为:"+this.banlance);
}
//取款()同步代码
public void drawAccount1(String name) throws InterruptedException {
synchronized (this) {//锁定某个对象
this.banlance=this.banlance-200;
Thread.sleep(100);
System.out.println(name+"取款后账户余额为:"+this.banlance);
}
}
//取款()同步方法
public synchronized void drawAccount2(String name) throws InterruptedException {
this.banlance=this.banlance-200;
Thread.sleep(100);
System.out.println(name+"取款后账户余额为:"+this.banlance);
}
}
class myThread6 extends Thread{
String name;
static Bank bank=new Bank("1", 1000);
public myThread6(String name) {
this.name = name;
}
public void run() {
while(1==1) {
if (bank.banlance>=200) {
try {
bank.drawAccount2(this.name);
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {
System.out.println("钱没了");
return;
}
}
}
}
线程死锁:
不同的线程都在等待不可能被释放的锁,多个线程同时被阻塞,因此所有的工作都无法完成。
在使用“synchronized”关键词时,很容易出现两个线程互相等待对方做出某个动作而出现死锁的情形。
避免死锁的技巧
当几个线程都要访问共享资源A,B,C时,保证使每个线程都按照同样的顺去去访问他们,例如全都先访问a,再访问b,最后访问c。
public static void main(String[] args) throws InterruptedException {
MyThread10 mt=new MyThread10("线程一");
MyThread10 mt1=new MyThread10("线程二");
mt.start();
Thread.sleep(100);
mt1.start();
}
}
class MyThread10 extends Thread{
static Object a=new Object();
static Object b=new Object();
String name;
public MyThread10(String name) {
this.name = name;
}
public void run(){
if ("线程一".equals(this.name)) {
synchronized(a) {
System.out.println(this.name+"锁定资源a");
try {
Thread.sleep(108);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(b) {
System.out.println(this.name+"锁定");
}
}
}if ("线程二".equals(this.name) ){
synchronized(b) {
System.out.println(this.name+"锁定资源b");
try {
Thread.sleep(108);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(a) {
System.out.println(this.name+"锁定资源a");
}
}
}
}
}