1.FutureTask类有什么作用?它实现了哪些接口? Callable接口和Runnable接口有什么不同?
Future是一个接口, FutureTask类是Future 的一个实现类,并实现了Runnable,因此FutureTask可以传递到线程对象Thread中新建一个线程执行。所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行。 如果在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给Future对象在后台完成,当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。
FutureTask是为了弥补Thread的不足而设计的,它可以让程序员准确地知道线程什么时候执行完成并获得到线程执行完成后返回的结果(如果有需要)。
Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;
Callable接口中的call()方法是有返回值的,是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。
2.volatile关键字有什么作用?
当线程没有执行结束就发生互换就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中变量值的副本,造成数据的不一致。
将变量声明为volatile,它指示JVM这个变量是不稳定的,每次使用它都到主存中读取。
3.Java提供了哪些同步机制来实现互斥?
1)对象监视器(monitor)与synchronized
synchronized的三种用法:
synchronized 代码块:监视器就是指定的对象。
synchronized 方法:监视器就是this对象。
synchronized 静态方法:监视器就是相应的Class对象
2.)Java并发包中的锁类:Lock接口,ReentrantLock类
4.编写Java程序模拟烧水泡茶最优工序。
package PaoCha;
public class Run{
public static void main(String[] args) {
shuihu hu = new shuihu();
shaoshui shao=new shaoshui();
xibei bei=new xibei();
Thread t1=new Thread (hu);
Thread t2=new Thread (shao);
Thread t3=new Thread (bei);
t1.setName("洗水壶");
t2.setName("烧水");
t3.setName("洗杯子");
t1.start();
t2.start();
t3.start();
try {
t1.join();
} catch (InterruptedException e) {
//等待洗水壶完成
e.printStackTrace();
}
try {
t2.join();
} catch (InterruptedException e) {
//等待烧水完成
e.printStackTrace();
}
try {
t3.join();
} catch (InterruptedException e) {
// 等待洗杯子完成
e.printStackTrace();
}
System.out.println("泡茶");
}
}
class shuihu implements Runnable{
public void run(){
System.out.println("洗水壶");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class shaoshui implements Runnable{
public void run(){
System.out.println("烧开水去");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("烧完水了");
}
}
class xibei implements Runnable{
public void run(){
for(int i=1;i<3;i++){
System.out.println("洗"+i+"个杯子");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
6.请使用Java并发包的Lock及Conditon改写例9.11。
class Accounter{
volatile private int value;
volatile private boolean isMoney = false;
//put设为同步方法
synchronized void put(int i) {
while(isMoney) {
try{
wait(); //等待并释放锁
} //线程等待
catch(Exception e){}
}
value = value + i;
System.out.println("存入"+i+" 账上金额为:"+value);
isMoney = true;//设置标志
notifyAll(); //唤醒等待资源的所有线程
}
synchronized int get(int i) {
while(!isMoney ){
try {
wait();
}
catch(Exception e){}
}
if (value>i)
value = value - i;
else {
i = value;
value = 0;
}
System.out.println("取走"+i+" 账上金额为:"+value);
isMoney = false;
notifyAll(); //不释放锁
return i;
}
}
class Products{
public static void main(String[] args) {
Accounter a1=new Accounter();
//存钱线程
new Thread(() -> {
while(true){ a1.put(100);}
}).start();
//取钱线程
new Thread(() -> {
while(true){ a1.get(100); }
}).start();
}
}
import java.util.concurrent.locks.*;
class Accounter{
volatile private int value;
volatile private boolean isMoney = false;
private final ReentrantLock lock=new ReentrantLock();
private Condition SaveCondition=lock.newCondition();
private Condition FetchCondition=lock.newCondition();
void put(int i) {
lock.lock();
try {
while (isMoney) {
try {
SaveCondition.await();
} catch (Exception e) {}
}
value = value + i;
System.out.println("存入" + i + " 账上金额为:" + value);
isMoney = true;
FetchCondition.signal();
}finally{
lock.unlock();
}
}
int get(int i) {
lock.lock();
try {
while (!isMoney) {
try {
FetchCondition.await();
} catch (Exception e) {
}
}
if (value > i)
value = value - i;
else {
i = value;
value = 0;
}
System.out.println("取走" + i + " 账上金额为:" + value);
isMoney = false;
SaveCondition.signal();
return i;
}finally{
lock.unlock();
}
}
}
class Products{
public static void main(String[] args) {
Accounter a1=new Accounter();
//存钱线程
new Thread(() -> {
while(true){ a1.put(100);}
}).start();
//取钱线程
new Thread(() -> {
while(true){ a1.get(100); }
}).start();
}
}
7. 编写一个多线程Java应用模拟生产者/消费者模型,各产生10个生产者和消费者线程,共享一个缓冲区队列(长度自设),生产者线程将产品放入到缓冲区,消费者线程从缓冲区取出产品。
class Huanchong {
private final int MAX_SIZE;//仓库的最大容量
private int count;//当前的货物数量
public Huanchong(int n){//初始化最大容量的构造方法
MAX_SIZE = n;
count = 0;
}
public synchronized void add(){//往仓库加货物的方法
while(count >= MAX_SIZE){//每次执行都判断仓库是否已满
System.out.println("已经满了");
try {
this.wait();//如果满了,就进入等待池
} catch (Exception e) {
e.printStackTrace();
}
}
count++;//数量加1
//打印当前仓库的货物数量
System.out.println(Thread.currentThread().toString()+"put"+count);
//仓库中已经有东西可以取了,则通知所有的消费者线程来拿
this.notifyAll();
}
public synchronized void remove(){//从仓库拿走货物的方法
while(count<=0){
System.out.println("空了");//每次执行都判断仓库是否为空
try {
this.wait();//如果为空,就进入等待池
} catch (Exception e) {
e.printStackTrace();
}
}
//打印当前仓库的货物数量
System.out.println(Thread.currentThread().toString()+"get"+count);
count--;//数量减1
//仓库还没装满,通知生产者添加货物
this.notifyAll();
}
}
class Producer extends Thread {
private Huanchong s;
public Producer(Huanchong s){
this.s = s;
}
public void run(){//线程方法
while(true){//循环
s.add();//往仓库加货物
try {
Thread.sleep(1000);//设置线程休息1s
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Consumer extends Thread {
private Huanchong s;
public Consumer(Huanchong s){
this.s = s;
}
public void run(){//线程方法
while(true){//循环
s.remove();//从仓库取走货物
try {
Thread.sleep(1500);//设置线程休息1.5s
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class Run{
public static void main(String[] args) {
Huanchong h = new Huanchong(10);
Thread p1 = new Producer(h);
Thread c1= new Consumer(h);
Thread p2 = new Producer(h);
Thread c2 = new Consumer(h);
p1.setName("producer1");
c1.setName("consumer1");
p2.setName("producer2");
c2.setName("consumer2");
//启动线程
p1.start();
c1.start();
p2.start();
c2.start();
}
}