线程
线程创建
继承Thread,重写run方法实现Runnable接口,实现run方法实现Callable接口,实现call方法(带返回值)
ExecutorService service
= Executors
.newFixedThreadPool(1);
Future submit
= service
.submit(callDemo1
);
System
.out
.println(submit
.get());
service
.shutdown();
常用方法
start()(开启线程)sleep(1000)(休眠1秒,不释放锁)setName()(设置线程的名字)getName()(获取线程的名字)getPriority()(获得当前的优先权,最高10,最低1,默认5。)interrupt()(终止休眠)
Thread thread
= new Thread(new SleepDemo1());
thread
.setName("小花");
thread
.start();
System
.out
.println(thread
.getName());
System
.out
.println(thread
.getPriority());
try {
Thread
.sleep(1000*5);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
thread
.interrupt();
}
@Override
public void run() {
System
.out
.println(Thread
.currentThread().getName()+"开启了");
try {
Thread
.sleep(1000*60*24);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
System
.out
.println(Thread
.currentThread().getName()+"结束了");
}
yield()(礼让线程)
@Override
public void run() {
for (int i
= 1; i
<= 100; i
++) {
if(i
%5==0){
Thread
.yield();
}
System
.out
.println(Thread
.currentThread().getName()+"-->已下载"+i
+"%。");
}
}
public static void main(String
[] args
) {
new Thread(new RunnableDemo1(),"图片").start();
for (int i
= 1; i
<= 100; i
++) {
System
.out
.println(Thread
.currentThread().getName()+"正在执行"+i
+"。");
}
}
此时图片线程又抢到了时间片,继续执行
run()
此时main线程抢到了时间片,继续执行
run()
join()(合并线程)
try {
t1
.join();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
setDeamon()(设置成守护线程)
线程分为用户线程和守护线程。只有当所有用户线程都结束,守护线程才会结束。
wait()(wait其实是Object的方法,线程等待并释放锁)notify()(恢复当前等待的线程,不释放锁)notifyAll()(恢复所有等待的线程)
public class ProducerDemo2 {
public static void main(String
[] args
) {
List list
= new ArrayList();
new Thread(new Producer1(list
), "A").start();
new Thread(new Customer1(list
), "B").start();
}
}
class Producer1 implements Runnable {
private List list
;
public Producer1(List list
) {
this.list
= list
;
}
@Override
public void run() {
while (true) {
synchronized (list
) {
if (list
.size() > 0) {
try {
list
.wait();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}
Object obj
= new Object();
list
.add(obj
);
System
.out
.println(Thread
.currentThread().getName() + "生产了-->" + obj
);
list
.notifyAll();
}
}
}
}
class Customer1 implements Runnable {
private List list
;
public Customer1(List list
) {
this.list
= list
;
}
@Override
public void run() {
while (true) {
synchronized (list
) {
if (list
.size() == 0) {
try {
list
.wait();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}
Object obj
= list
.remove(0);
System
.out
.println(Thread
.currentThread().getName() + "消费了-->" + obj
);
list
.notifyAll();
}
}
}
}
线程安全
触发条件
多线程并发有共享数据共享数据有修改操作
public class BackDemo1 {
public static void main(String
[] args
) {
Account act
=new Account(10000);
new Thread(new Bank(act
),"A").start();
new Thread(new Bank(act
),"B").start();
}
}
class Account {
private double balance
;
public Account(double balance
) {
this.balance
= balance
;
}
public double getBalance() {
return balance
;
}
public void setBalance(double balance
) {
this.balance
= balance
;
}
void getMoney(double money
){
double before
= this.getBalance();
double after
= before
- money
;
try {
Thread
.sleep(10);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
this.setBalance(after
);
}
}
class Bank implements Runnable{
private Account act
;
public Bank(Account act
) {
this.act
= act
;
}
@Override
public void run() {
double money
=5000;
act
.getMoney(money
);
System
.out
.println(Thread
.currentThread().getName()+"还剩"+act
.getBalance());
}
}
解决方法
synchronized(线程同步)
synchronized (共享对象
){
}
1.在代码块中加上synchronized
synchronized (this) {
double before
= this.getBalance();
double after
= before
- money
;
try {
Thread
.sleep(10);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
this.setBalance(after
);
}
2.在方法上加synchronized
共享对象只能是this,同步范围是一整个方法。对象锁,一百个对象一百个锁。
**优点:**方便、简洁。
**缺点:**范围大,性能低。
synchronized void getMoney(double money
){
double before
= this.getBalance();
double after
= before
- money
;
try {
Thread
.sleep(10);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
this.setBalance(after
);
}
3.在静态方法上加synchronized
类锁,一百个对象一个锁。
synchronized static void getMoney(double money
){
double before
= this.getBalance();
double after
= before
- money
;
try {
Thread
.sleep(10);
} catch (InterruptedException e
) {
e
.printStackTrace();
}
this.setBalance(after
);
}