Java多线程例子
Java多线程的思路就是一个:如果保证线程之间能够协作
首先我们得了解什么叫作线程,我们电脑里面有很多程序在运行,比如说QQ,微信等等,一个程序就是一个进程,进程是电脑分配内存空间的最小单位,但是进程里面有很多线程,比如说QQ,QQ里面有接受消息的,有显示动画的,有发送消息的,有很多很多线程,线程就是CPU执行命令的最小单位,一个CPU在一个时间内只能执行一个线程的任务
线程可以生成,运行,杀死,让其休眠.我们可以巧妙使用线程来完成许多协作的问题
我们可以构建线程池:如果有大量的任务要运行,会导致频繁创建新线程、销毁线程。线程池维护多个创建好的线程,同时可以让多个任务“复用”线程,避免了线程的重复创建和销毁。
我们还可以给资源上锁
可以使用synchronized(this) { …}给()里面的资源上锁,通过加锁:一个线程要进入同步方法,首先拿到锁,进入方法后立刻上锁,导致其他要进入这个方法的线程被阻塞(等待锁):表达式expr求值结果必须是一个对象的引用,因此可以通过对任何对象加锁来同步语句块,如果expr指向的对象没有被加锁,则第一个执行到同步块的线程对该对象加锁,线程执行该语句块,然后解锁;如果expr指向的对象已经加了锁,则执行到同步块的其它线程将被阻塞.expr指向的对象解锁后,所有等待该对象锁的线程都被唤醒,注意只是执行到同步块的线程加锁,而且如果同步块不是静态上下文的话就只对这个对象加锁
2. 给定下列程序:
public class Holder {
private int data = 0;
public int getData () {return data;}
public synchronized void inc (int amount) {
int newValue = data + amount;
try {Thread.sleep(5);
} catch (InterruptedException e) {}
data = newValue;
}
public void dec (int amount) {
int newValue = data - amount;
try {Thread.sleep(1);
} catch (InterruptedException e) {}
data = newValue;
}
}
public static void main (String [] args) {
ExecutorService es = Executors.newCachedThreadPool();
Holder holder = new Holder ();
int incAmount = 10, decAmount = 5, loops = 100;
Runnable incTask = () -> holder.inc(incAmount);
Runnable decTask = () -> holder.dec(decAmount);
for (int i = 0; i < loops; i++) {
es. execute(incTask);
es. execute(decTask);
}
es. shutdown ();
while (! es. isTerminated ()) {}
}
下列说法正确的是_____A______。
A. 当一个线程进入holder对象的inc方法后,holder对象被锁住,因此其他线程不能进入inc方法和dec方法
B. 当一个线程进入holder对象的inc方法后,holder对象被锁住,因此其他线程不能进入inc方法,但可以进入dec方法
C. 当一个线程进入holder对象的dec方法后,holder对象被锁住,因此其他线程不能进入dec方法和inc方法
D. 当一个线程进入holder对象的dec方法后,holder对象被锁住,因此其他线程不能进入dec方法,但可以进入inc方法
当然可以使用lock.lock()和unlock()方法给this加锁
还可以使用Condition类来加锁,注意一定要声明锁才能使用Condition里面的await和signalALL方法,这个可以进行线程协作和信号通信
还有多线程的请求是并发的不是串行的,对于并发的请求,可以构建一个List来进行处理
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReusableThread extends Thread{
//private Runnable runTask = null; //保存接受的线程任务
//使用一个列表接收所有需要完成的任务
private LinkedList<Runnable> tasks = new LinkedList<>();
private static Lock lock = new ReentrantLock();
private static Condition waitTask = lock.newCondition();
//只定义不带参数的构造函数
public ReusableThread(){
super();
}
/**
* 覆盖Thread类的run方法
*/
@Override
public void run() {
while (true) {
lock.lock();
try{
if (tasks.size() == 0) {
try {
waitTask.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//移除并获取列表第一个任务,运行
tasks.removeFirst().run();
}finally {
lock.unlock();
}
}
}
/**
* 提交新的任务
* @param task 要提交的任务
*/
public void submit(Runnable task){
lock.lock();
try{
tasks.add(task);
waitTask.signalAll();
}finally {
lock.unlock();
}
}
public static void main(String[] args){
Runnable task1 = new Runnable() {
@Override
public void run() {
System.out.println("Thread " + Thread.currentThread().getId() + ": is running " + toString());
try { Thread.sleep(200); }
catch (InterruptedException e) { e.printStackTrace(); }
}
@Override
public String toString() {
return "task1";
}
};
Runnable task2 = new Runnable() {
@Override
public void run() {
System.out.println("Thread " + Thread.currentThread().getId() + " is running " + toString());
try { Thread.sleep(100); }
catch (InterruptedException e) { e.printStackTrace(); }
}
@Override
public String toString() {
return "task2";
}
}
}
0 条评论