1. volatile关键字有什么作用
- volatile意为不稳定的,提示编译器禁止对其修饰的数据进行优化。
- 现代CPU工作时,先将数据从主存取出,加载到相应核心的寄存器中,再对其进行运算;而在多线程程序中,由于多核可见性受限,核心操作的是缓存中的副本,导致数据不同步。volatile关键字标识数据后,在程序运行时,该数据不加载到缓存中,直接操作主存中的数据。
2. 编写Java程序模拟烧水泡茶最优工序
/**
* @title:泡茶程序模拟
* @author YEE686
* @version 20.11.10
*/
class ThreadA implements Runnable{
Thread tb = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("第1min:开始洗茶壶");
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第2min:洗茶壶完成\n" +"第2min:开始洗茶杯");
try {
Thread.sleep(2*600);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第4min:洗茶杯完成\n"+"第4min:开始拿茶叶");
try {
Thread.sleep(5*600);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第5min:拿茶叶完成\n线程2工作完成");
}
});
@Override
public void run() {
System.out.println("第0min:开始洗水壶");
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第1min:洗水壶完成\n"+"第1min:开始烧水");
tb.start();
try {
Thread.sleep(15*600);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第16min:烧水完成\n"+"第16min:开始泡茶\n"+
"线程1工作完成");
}
}
public class Tea {
public static void main(String[] args) {
ThreadA tta = new ThreadA();
Thread tea = new Thread(tta);
tea.start();
try{
tea.join();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("泡茶完成");
}
}
}
3. 编写Java程序模拟烧菜上菜流程
问题:各产生10个生产值和消费者线程,共享一个缓冲区队列,生产值线程将产品放入到缓冲区中,消费者从缓冲区取出产品。
/**
* @title:烧菜上菜模拟
* @author YEE686
* @version 20.11.06
*/
class table {
private volatile int dishes = 0;
public static int MakeCounter = 0;
public static int GetCounter = 0;
synchronized public void makeDish() {
if (dishes < 10) {
dishes++;
System.out.println(Thread.currentThread().getName()+
" 做了菜 "+dishes);
notifyAll();
MakeCounter++;
} else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized public void getDish() {
if (dishes > 0) {
System.out.println(Thread.currentThread().getName()+
" 拿了菜 "+dishes);
dishes--;
notifyAll();
GetCounter++;
} else {
try{
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class producer implements Runnable {
table tb;
@Override
public void run() {
for(int i=0; i<5; i++) {
tb.makeDish();
}
}
public void fetch(table tb) {
this.tb = tb;
}
}
class consumer implements Runnable {
table tb;
@Override
public void run() {
for(int i=0; i<5; i++) {
tb.getDish();
}
}
public void fetch(table tb) {
this.tb = tb;
}
}
public class Restaurant {
public static void main(String[] args) {
table tb = new table();
producer pd = new producer(); pd.fetch(tb);
consumer cn = new consumer(); cn.fetch(tb);
Thread[] pr,cs; //生产者线程组 消费者线程组
pr = new Thread[10]; cs = new Thread[10];
for(int i=0; i<10; i++) {
pr[i] = new Thread(pd,"生产者"+i+"线程");
}
for(int i=0;i<10; i++) {
cs[i] = new Thread(cn,"消费者"+i+"线程");
}
for(int i=0; i<10; i++) {
pr[i].start();
cs[i].start();
}
try{
for(int i=0; i<10; i++) {
pr[i].join();
cs[i].join();
}
} catch (InterruptedException is) {
is.printStackTrace();
}
System.out.println("一共做了"+table.MakeCounter+"道菜");
System.out.println("一共拿了"+table.GetCounter+"道菜");
}
}
存在问题1:最后打印数目不是50和50
存在问题2:会造成死锁
存在问题3:不清楚每个线程各生成和消费多少此
版权声明:本文为weixin_45750637原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。