2019-03-01 21:36:42 卢浮宫 版权声明:本文为站长原创文章,转载请写明出处
1、实现Runnable接口,重写run方法,代码如下:
public class XaThread implements Runnable {
public static void main(String[] args) throws InterruptedException {
XaThread xaThread = new XaThread();
Thread mThread = new Thread(xaThread);
mThread.start();
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(i);
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
2、继承Thread类,代码如下:
public class Xthread{
public static void main(String[] args) {
Thread myThread = new MyThread();
myThread.start();
}
}
class MyThread extends Thread{
public void run(){
for (int i = 0; i < 100; i++) {
System.out.println(i);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3、两者对比:
① 继承Thread类后就是单继承了,会隔绝来自其他类的继承,而实现Runnable接口则消除了这种不良。
② class Thread implements Runnable {...}可以看到继承了Thread类后还是要实现Runnable接口,
会产生多个Runnable示例对象。而实现Runnable则不会,可以多线程处理同一资源,使用一个Runnable示例产生多个线程,且可以资源共享。
①新建:新建了一个线程(继承Thread类或实现Runnable接口)
②可运行:线程创建后且调用了start方法,则进入线程池,等待被线程调度选用,获取cpu的使用权
③运行:可执行的线程获取到了cpu资源,并执行程序代码
④阻塞:线程因为某种原因放弃了cpu使用权,暂停了操作,直到转换成可运行状态才有机会继续进行操作。
⑤死亡:线程run()main()方法执行完成,或者异常抛出后,线程结束,且不可恢复。
1、当前线程运行Thread.sleep(1000);会使当前线程休眠1s,进入阻塞状态
2、运行在当前线程(Thread1)的其他线程(Thread2)调用join方法时,会把Thread2加入执行,Thread1阻塞
3、等待用户输入时(执行IO操作)当前线程进入阻塞状态
4、使用Thread.sleep(1000);当前线程阻塞,但不释放对象锁
5、Thread.join();当前线程进入阻塞,但不释放对象锁,等待Thread完成后继续运行
6、Object.wait();线程进入阻塞,同时释放对象锁,进入等待列队。使用notify()、或notifyAll()可以唤醒
7、notify()是唤醒一个任意线程,notifyAll()是唤醒所有等待的线程
1、锁是只有在同步中才有的概念。
2、乐观锁和悲观锁不单单指锁的类型,事实上是指怎么对待数据并发同步
3、悲观锁认为数据被拿走就会被修改,所以在每次拿数据时都会上锁。别人在拿这个数据时就会阻塞,知道它获取到锁
4、乐观锁则认为数据被拿走后不会被修改,所以不会上锁。但是要注意:需要判断期间数据有没有被修改过。
5、java中的synchronized就是实现的悲观锁,而乐观锁则适用与读操作比较频繁情况(可以提高吞吐量)
1、死锁的原因及排查方案
死锁的本质在于对资源的不良竞争。当多线程同时被阻塞,他们中的一个或全部都在等待一个资源被释放,但是这个资源又被其他线程锁定,
2、死锁的产生条件:
①互斥占用:一个资源被占用时其他不能使用。②不可抢占:只能等待资源被释放。③请求和保持:请求其他资源时保持对原有资源占用。
④循环:1占用2,2占用3,3占用4,4占用1(花盆上的毛毛虫)
1、不可避免会有使用同步的情况,关于线程同步有以下方案:
①在同步方法中假如synchronize关键字
②使用synchronize快对代码段进行同步处理
public class ProAndCon {
//定义最大容量
private int maxNum = 2;
//产品储存
private LinkedList<Integer> list = new LinkedList<>();
class Producer implements Runnable{
@Override
public void run() {
synchronized(list){
while(list.size() == maxNum){
System.out.println("仓库已满,停止生产");
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(1);
System.out.println("生产中,数量为--" + list.size());
list.notify();
}
}
}
class Customer implements Runnable{
@Override
public void run() {
synchronized(list){
while(list.size() == 0){
System.out.println("没有库存,停止消费");
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.removeFirst();
System.out.println("消费量一个,当前库存为--" + list.size());
list.notify();
}
}
}
public static void main(String[] args) {
ProAndCon proAndCon = new ProAndCon();
Producer producer = proAndCon.new Producer();
Customer customer = proAndCon.new Customer();
for (int i = 0; i < 10; i++) {
Thread proThread = new Thread(producer);
proThread.start();
Thread comThread = new Thread(customer);
comThread.start();
}
}
}
输出结果如下:
生产中,数量为--1
消费量一个,当前库存为--0
生产中,数量为--1
消费量一个,当前库存为--0
生产中,数量为--1
消费量一个,当前库存为--0
生产中,数量为--1
消费量一个,当前库存为--0
生产中,数量为--1
消费量一个,当前库存为--0
生产中,数量为--1
生产中,数量为--2
消费量一个,当前库存为--1
消费量一个,当前库存为--0
生产中,数量为--1
生产中,数量为--2
仓库已满,停止生产
消费量一个,当前库存为--1
消费量一个,当前库存为--0
生产中,数量为--1
消费量一个,当前库存为--0