51、启动一个线程是用run()还是start()?
启动一个线程是调用start()方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。
52、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
如果其它方法中使用当前对象作为锁对象,则不能;
如果其它方法中没有使用当前对象作为锁对象,则能。
53、线程的基本概念、线程的基本状态以及状态之间的关系
在多任务操作系统中,为了提高CPU的利用率,可以使用多进程编程。但对进程通信比较困难,进程间数据不能共享,因此可以使用多线程编程。一个进程至少包含一个主入口线程。
单个CPU,在同一时间只能处理一个线程的数据,但是操作系统的任务调度非常快,人眼无法识别,感觉上是多个线程同时执行。有的线程可以已经用完CPU,正在作磁盘操作,此时并不使用CPU,可以让出CPU资源给其它线程使用,提高效率。
线程有生命周期及相关关系和对应方法见46题。
54、简述synchronized和java.util.concurrent.locks.Lock的异同?
主要相同点:Lock能完成synchronized所实现的所有功能
主要不同点:
1.更好的语义
2.更高性能
3.synchronized自动释放锁,Lock手动释放,并且必须在finally从句中释放。
4.功能强大,可以用tryLock方法可以非阻塞方式去拿锁
举例说明(对下面的题用lock进行了改写):
package com.huawei.interview;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest {
private int j;
private Lock lock = newReentrantLock();
public static void main(String[] args) {
ThreadTest tt = new ThreadTest();
for (int i = 0; i < 2; i++) {
new Thread(tt.new Adder()).start();
new Thread(tt.new Subtractor()).start();
}
}
private class Subtractor implements Runnable {
@Override
public void run() {
while (true) {
lock.lock();
try {
System.out.println("j--=" + j--);
} finally {
lock.unlock();
}
}
}
}
private class Adder implements Runnable {
@Override
public void run() {
while (true) {
lock.lock();
try {
System.out.println("j++=" + j++);
} finally {
lock.unlock();
}
}
}
}
}
55、设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题。
public class ThreadTest1 {
private int j;
public static void main(String args[]) {
ThreadTest1 tt = new ThreadTest1();
Inc inc = tt.new Inc();
Dec dec = tt.new Dec();
for (inti = 0; i < 2; i++) {
Thread t = new Thread(inc);
t.start();
t = new Thread(dec);
t.start();
}
}
private synchronized void inc() {
j++;
System.out.println(Thread.currentThread().getName() + "-inc:" + j);
}
private synchronized void dec() {
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
class Inc implements Runnable {
public void run() {
for (inti = 0; i < 100; i++) {
inc();
}
}
}
class Dec implements Runnable {
public void run() {
for (inti = 0; i < 100; i++) {
dec();
}
}
}
}