一、多线程简介
1:要想说线程,首先必须得聊聊进程,因为线程是依赖于进程存在的。
2:那么,什么是进程?
进程就是正在运行的程序,是系统进行资源分配和调用的独立单位。每一个进程都有它自己的内存空间和系统资源。
3:多进程有什么意义呢?
单进程计算机只能做一件事情。而我们现在的计算机都可以一边玩游戏(游戏进程),一边听音乐(音乐进程),所以我们常见的操作系统都是多进程操作系统。比如:Windows,Mac和Linux等,能在同一个时间段内执行多个任务。
对于单核计算机来讲,游戏进程和音乐进程是同时运行的吗?不是。
因为CPU在某个时间点上只能做一件事情,计算机是在游戏进程和音乐进程间做着频繁切换,且切换速度很快,所以,我们感觉游戏和音乐在同时进行,其实并不是同时执行的。
多进程的作用不是提高执行速度,而是提高CPU的使用率。
4:那么什么又是线程呢?
在一个进程内部又可以执行多个任务,而这每一个任务我们就可以看成是一个线程。线程是程序中单个顺序的控制流,是程序使用CPU的基本单位。
5:多线程有什么意义呢?
多线程的作用不是提高执行速度,而是为了提高应用程序的使用率。
而多线程却给了我们一个错觉:让我们认为多个线程是并发执行的。其实不是。
因为多个线程共享同一个进程的资源(堆内存和方法区),但是栈内存是独立的,一个线程一个栈。所以他们仍然是在抢CPU的资源执行。一个时间点上只有能有一个线程执行。而且谁抢到,这个不一定,所以,造成了线程运行的随机性。
二、创建任务和线程1. 实现方法一
- package
test; - public
class Test { -
public static void main(String[] args) { -
//创建任务 -
PrintString print = new PrintString("jiang"); -
//创建任务的线程 -
Thread thread = new Thread(print); -
//调用start告诉java虚拟机线程已准备就绪 -
thread.start(); -
} - }
-
- //定义任务类,实现Runnable接口,重载run方法
- class
PrintString implements Runnable{ -
private String strToPrint; -
public PrintString(String str){ -
this.strToPrint = str; -
} -
public void run() { -
System.out.println(this.strToPrint); -
} - }
2. 实现方法二
- package
test; - public
class Test { -
public static void main(String[] args) { -
TestThread tt = new TestThread("qin"); -
tt.start(); -
} - }
- //直接定义Thread类的扩展类,实现run方法
- class
TestThread extends Thread{ -
private String strToPrint; -
public TestThread(String str){ -
this.strToPrint = str; -
} -
public void run() { -
System.out.println(this.strToPrint); -
} - }
三、Thread类
- public
class TestRunnable1 implements Runnable { -
@Override -
public void run() { -
for (int i = 1; i <= 1000; i++) { -
System.out.println("A : " + i); -
} -
} - }
-
- public
class TestRunnable2 implements Runnable { -
@Override -
public void run() { -
for (int i = 1; i <= 1000; i++) { -
System.out.println("B : " + i); -
} -
} - }
-
- public
class TestThead { -
public static void main(String[] args) { -
Thread t1 = new Thread(new TestRunnable1()); -
Thread t2 = new Thread(new TestRunnable2()); -
t1.setPriority(6); -
t2.setPriority(Thread.MAX_PRIORITY); -
System.out.println("A Priority : " + t1.getPriority()); -
System.out.println("B Priority : " + t2.getPriority()); -
t1.start(); -
t2.start(); -
} - }
四、线程的状态
五、线程同步
1. synchronized
- //测试同步方法
- public
synchronized void printStri(){ -
for(int i=0; i<100;i++){ -
System.out.println(i); -
} - }
-
- //测试同步块,同步语句不仅可以对this对象加锁,而且可用于对任务对象加锁。
- public
void printStri(){ -
synchronized(this){ -
for(int i=0; i<100;i++){ -
System.out.println(i); -
} -
} - }
2. 利用加锁同步
- private
static class PrintStr{ -
//创建一个锁 -
private static Lock lock = new ReentrantLock(); -
//测试同步方法 -
public void printStr(){ -
//加锁 -
lock.lock(); -
try{ -
for(int i=0; i<100;i++){ -
System.out.println(i); -
} -
} catch(Exception e){ -
e.printStackTrace(); -
}finally { -
//解锁 -
lock.unlock(); -
} -
} - }
六、线程通信
- package
test; - import
java.util.concurrent.ExecutorService; - import
java.util.concurrent.Executors; - import
java.util.concurrent.locks.Condition; - import
java.util.concurrent.locks.Lock; - import
java.util.concurrent.locks.ReentrantLock; -
- public
class TestCondition { -
private static Account account = new Account(); -
public static void main(String[] args) { -
ExecutorService executorService = Executors.newFixedThreadPool(2); -
executorService.execute(new DepositTask()); -
executorService.execute(new WithdrawTask()); -
executorService.shutdown(); -
} -
-
-
public static class DepositTask implements Runnable { -
@Override -
public void run() { -
try { -
account.deposit((int) (Math.random() * 10) + 1); -
Thread.sleep(1000); -
} catch (InterruptedException e) { -
// TODO: handle exception -
} -
} -
} -
-
-
public static class WithdrawTask implements Runnable { -
@Override -
public void run() { -
while (true) { -
account.withdraw((int) (Math.random() * 10) + 1); -
} -
} -
} -
-
-
public static class Account { -
private static Lock lock = new ReentrantLock(); -
private static Condition newDeposit = lock.newCondition(); -
private int balance = 0; // 账户金额 -
-
public int getBalance() { -
return balance; -
} -
-
public void withdraw(int amount) { -
lock.lock(); -
try { -
while (balance < amount) { -
System.out.println("余额不足,等待充值"); -
newDeposit.await(); -
} -
balance -= amount; -
System.out.println("取款:" + amount + "余额:" + balance); -
} catch (InterruptedException e) { -
// TODO: handle exception -
} finally { -
lock.unlock(); -
} -
} -
-
public void deposit(int amount) { -
lock.lock(); -
try { -
while (balance < 10) { -
balance += amount; -
System.out.println("充值:" + amount + "余额:" + balance); -
newDeposit.signalAll(); -
} -
} finally { -
lock.unlock(); -
} -
} -
} - }