1、进程和线程的区别:每个进程都有独立的代码和数据空间,进程间的切换会有较大的开销。线程可以看成是轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器,线程切换的开销小。Java的线程是通过java.lang.Thread类来实现的。
2、每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。通过调用Thread类start()方法来启动一个线程。
3、
方法名 | 解释 |
---|---|
isAlive() | 判断线程是否还“活”着,即线程是否还未终止 |
getPriority() | 获得线程的优先级数值 |
setPriority() | 设置线程的优先级数值 |
Thread.sleep() | 让当前线程睡眠指定的毫秒数 |
join() | 调用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行 |
yield() | 让出cpu,当前线程进入就绪队列等待调度 |
wait() | 当前线程进入对象的wait pool |
notify()/notifyAll() | 唤醒对象的wait pool中的一个/所有等待线程 |
以上是线程控制的一些基本方法
4、Java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时,将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,不被其他线程调用,从而保证了该变量的唯一性和准确性。
5、线程死锁
public class Test implements Runnable{
static Object o1 = new Object();
static Object o2 = new Object();
int flag;
public void run(){
System.out.println("flag="+this.flag);
if(flag == 0){
synchronized(o1){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized(o2){
System.out.println("flag == 0");
}
}
if(flag == 1){
synchronized(o2){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized(o1){
System.out.println("flag == 1");
}
}
}
public static void main(String args[]) {
Test t1 = new Test();
t1.flag = 0;
Test t2 = new Test();
t2.flag = 1;
Thread tt1 = new Thread(t1);
Thread tt2 = new Thread(t2);
tt1.start();
tt2.start();
}
}
6、生产者消费者问题
public class ProducerConsumer{
public static void main(String args[]){
Basket bk = new Basket();
Producer p = new Producer(bk);
Consumer c = new Consumer(bk);
new Thread(p).start();
new Thread(c).start();
}
}
class Bread{
int id;
Bread(int id){
this.id = id;
}
}
class Basket{
Bread breadArray[] = new Bread[8];
int index = 0;
public synchronized void push(Bread b){
while(index == breadArray.length){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
breadArray[index] = b;
index++;
}
public synchronized Bread pop(){
while(index == 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
index--;
return breadArray[index];
}
}
class Producer implements Runnable{
Basket bk = null;
long time = 0;
Producer(Basket bk){
this.bk = bk;
}
public void run() {
for(int i=0;i<20;i++){
Bread b = new Bread(i);
bk.push(b);
System.out.println("生产了第"+b.id+"个面包。");
try {
time = (long)(Math.random()*200);
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(time);
}
}
class Consumer implements Runnable{
Basket bk = null;
Bread temp = null;
long time = 0;
Consumer(Basket bk){
this.bk = bk;
}
public void run() {
for(int i=0;i<20;i++){
temp = bk.pop();
System.out.println("消费了第"+temp.id+"个面包。");
try {
time = (long)(Math.random()*1000);
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(time);
}
}