前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java多线程例子

Java多线程例子

作者头像
用户7267083
发布2022-12-08 14:20:14
4130
发布2022-12-08 14:20:14
举报
文章被收录于专栏:sukuna的博客sukuna的博客

Java多线程例子

于2021年4月29日2021年4月29日由Sukuna发布

Java多线程的思路就是一个:如果保证线程之间能够协作

首先我们得了解什么叫作线程,我们电脑里面有很多程序在运行,比如说QQ,微信等等,一个程序就是一个进程,进程是电脑分配内存空间的最小单位,但是进程里面有很多线程,比如说QQ,QQ里面有接受消息的,有显示动画的,有发送消息的,有很多很多线程,线程就是CPU执行命令的最小单位,一个CPU在一个时间内只能执行一个线程的任务

线程可以生成,运行,杀死,让其休眠.我们可以巧妙使用线程来完成许多协作的问题

我们可以构建线程池:如果有大量的任务要运行,会导致频繁创建新线程、销毁线程。线程池维护多个创建好的线程,同时可以让多个任务“复用”线程,避免了线程的重复创建和销毁。

我们还可以给资源上锁

可以使用synchronized(this) { …}给()里面的资源上锁,通过加锁:一个线程要进入同步方法,首先拿到锁,进入方法后立刻上锁,导致其他要进入这个方法的线程被阻塞(等待锁):表达式expr求值结果必须是一个对象的引用,因此可以通过对任何对象加锁来同步语句块,如果expr指向的对象没有被加锁,则第一个执行到同步块的线程对该对象加锁,线程执行该语句块,然后解锁;如果expr指向的对象已经加了锁,则执行到同步块的其它线程将被阻塞.expr指向的对象解锁后,所有等待该对象锁的线程都被唤醒,注意只是执行到同步块的线程加锁,而且如果同步块不是静态上下文的话就只对这个对象加锁

代码语言:javascript
复制
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来进行处理

代码语言:javascript
复制
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";
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年4月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java多线程例子
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档