多线程的创建
1. extends Thread
class MyThread extends Thread{
2. implements Runnable
class MyThread implements Runnable{
3. 两者优劣比较
一般情况下用implements Runnable比较容易实现资源共享,我比较喜欢用这种方式创建多线程。
其实还有一种方法就是实现Callable接口。这个我不太熟。
多线程Thread类的一些其他属性和方法
setName和getName
Thread.currentThread().getName(); //获取当前线程的名字
Thread.currentThread().setName(); //设置当前线程的名字
setPriority和getPriority
public class TestPriority implements Runnable{
join
public class TestJion implements Runnable{
插队行为
sleep
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
一般用来放大线程之间的竞争关系
多线程中的状态
-
NEW
-
RUNNABLE
-
TIMED_WAITING
-
TERMINATED
public class TestState {
public static void main(String[] args) {
Thread thread = new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("///////////");
});
Thread.State state = thread.getState();
System.out.println(state);
thread.start();
state = thread.getState();
System.out.println(state);
while(state!=Thread.State.TERMINATED){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
state=thread.getState();
System.out.println(state);
}
}
}
-
补充:BLOCKED,WAITING
多线程中并发问题的处理
1. synchronized
synchronized public class UnSafeBank {
public static void main(String[] args) {
Account account = new Account("结婚基金",1000);
Drawing you = new Drawing(account,50,"you");
Drawing girlFriend = new Drawing(account,100,"girlFriend");
Drawing you_2=new Drawing(account,50,"you");
you.start();
girlFriend.start();
you_2.start();
}
}
class Account {
String name;
int accountMoney;
public Account(String name, int accountMoney) {
this.name = name;
this.accountMoney = accountMoney;
}
}
class Drawing extends Thread{
Account account;
int drawMoney;
int nowMoney;
public Drawing(Account account, int drawMoney,String name) {
this.account = account;
this.drawMoney = drawMoney;
this.setName(name);
}
这里的synchronized应该锁住的是account对象,而不是Drawing类中的run方法。
synchronized有两种方法:
-
放在类方法的返回值前,表示锁住了this对象
-
synchronized(obj),锁住被共享的数据对象,只有当一个线程操作完了再释放。
2. lock
public class BuyTicket implements Runnable{
int tickets=20;
boolean flag=true;
private final ReentrantLock lock = new ReentrantLock();
在Runnable实现类里面加一把锁private final ReentrantLock lock = new ReentrantLock();
在需要锁的方法里,加入lock.lock();然后用try{}把其他代码塞到大括号里面,最后finally{lock.unlock();}解锁
线程通信基础:生产者消费者模式
1. 一对一
public class Main {
public static void main(String[] args) {
Breakfast breakfast = new Breakfast();
new Thread(new Producer(breakfast)).start();
new Thread(new Consumer(breakfast)).start();
}
}
class Producer implements Runnable{
private Breakfast breakfast;
public Producer(Breakfast breakfast) {
this.breakfast = breakfast;
}