标签:out object 通知 java多线程 不可 prefix 操作 throws 代码块
synchronized关键字实现多线程同步
public class TestSynchronized {
public static void main(String[] args) throws InterruptedException {
Test test = new Test();
List<Thread> listThread = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 100; j++) {
test.Increase();
}
}
});
listThread.add(thread);
thread.start();
}
// 主线程等待所有子线程执行完成
for (Thread t : listThread) {
t.join();
}
test.print();
}
}
class Test {
int i = 0;
public synchronized void Increase() {
i++;
}
public void print() {
System.out.println(i);
}
}
synchronized配合wait、notify实现生产者消费者
public class ProducerConsumer {
public static void main(String[] args) {
ProCon proCon = new ProCon();
//生产者
new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 20; i++) {
proCon.pro(i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
}
}
}).start();
//消费者1
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
proCon.con();
Thread.sleep(3000);
}
} catch (InterruptedException e) {
}
}
}).start();
//消费者2
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
proCon.con();
Thread.sleep(3000);
}
} catch (InterruptedException e) {
}
}
}).start();
}
}
class ProCon {
List<Integer> listProduct = new ArrayList<Integer>();
public synchronized void pro(int pro) throws InterruptedException {
if (listProduct.size() > 100) {
System.out.println(getPrefix() + "库存已满,请稍候再生产");
wait();
}
listProduct.add(pro);
System.out.println(getPrefix() + "生产了:" + pro);
notifyAll();// 通知消费者获取产品
}
public synchronized void con() throws InterruptedException {
if (listProduct.size() <= 0) {
System.out.println(getPrefix() + "库存不足,请及时补货");
wait();
}
Integer cur = listProduct.get(0);
listProduct.remove(cur);
System.out.println(getPrefix() + "取走:" + cur + " 剩余库存:" + listProduct.toString());
notifyAll();// 通知生产者生产产品
}
private String getPrefix() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ").format(new Date()) + Thread.currentThread().getName() + " ";
}
}
多线程的内存模型:main memory(主存)、working memory(线程栈),线程处理数据时,先把主存中的数据load到本地栈,操作完成后会save回主存,volatile关键词的作用:每次针对该变量的操作都激发一次load and save。
针对多线程使用的变量如果不是volatile或者final修饰的,很有可能产生不可预知的结果(另一个线程修改了这个值,但是之后在某线程看到的是修改之前的值)。其实道理上讲同一实例的同一属性本身只有一个副本。但是多线程是会缓存值的,本质上,volatile就是不去缓存,直接取值。在线程安全的情况下加volatile会牺牲性能。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class TestThread {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 1、继承Thread类,资源和Thread绑定,资源无法共享
new Thread1().start();
new Thread1().start();
// 2、实现Runnable接口,资源和Runnable接口绑定,资源可以共享
Thread2 thread2 = new Thread2();
new Thread(thread2).start();
new Thread(thread2).start();
// 3、实现Callable<>接口
ExecutorService e = Executors.newFixedThreadPool(3);
Future future = e.submit(new Thread3());
// future.isDone(); // return true,false 无阻塞
String str = (String) future.get(); // return 返回值,阻塞直到该线程运行结束
System.out.println("主线程结束");
System.out.println(str);
}
}
// 1、继承Thread类
class Thread1 extends Thread {
int i = 0;
@Override
public void run() {
i++;
System.out.println(i);
}
}
// 2、实现Runnable接口
class Thread2 implements Runnable {
int i = 0;
@Override
public void run() {
i++;
System.out.println(i);
}
}
// 3、实现Callable<>泛型接口
// 可以在任务结束后提供一个返回值,Runnable不行
// call方法可以抛出异常,Runnable的run方法不行
// 可以通过运行Callable得到的Fulture对象监听目标线程调用call方法的结果,得到返回值,(fulture.get(),调用后会阻塞,直到获取到返回值)
class Thread3 implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(3000);
System.out.println("子线程结束");
return "test";
}
}
未完待续。。。
标签:out object 通知 java多线程 不可 prefix 操作 throws 代码块
原文地址:https://www.cnblogs.com/yinchh/p/12381089.html