Beginners learn Java network programming
- 2021-10-24 22:50:02
- OfStack
Running thread
Create a subclass of Thread
public class ThreadChild extends Thread {
@Override
public void run() {
while (true) {
System.out.println("run");
}
}
}
public class Test {
public static void main(String[] args) throws Exception {
ThreadChild t = new ThreadChild();
t.start();
}
}
Create an Thread incoming Runnable interface implementation class
public class RunnableImpl implements Runnable {
@Override
public void run() {
while (true) {
System.out.println("run");
}
}
}
public class Test {
public static void main(String[] args) throws Exception {
Thread t = new Thread(new RunnableImpl());
t.start();
}
}
Callback
Submit () of ExecutorService thread pool can receive Runnable or Callable. Callable has a return value after execution, but Runnable has no return value after execution. The return value can be obtained by get method of Future of submit. It should be noted that get method is a blocking method. If the thread is not executed, it will block get () until the thread executes and returns data.
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<Integer> future = executorService.submit(() -> {
TimeUnit.SECONDS.sleep( 3);
return 1;
});
Future<?> future2 = executorService.submit(() -> {
});
Future<String> future3 = executorService.submit(() -> {
}, "aaa");
System.out.println(future.get());
System.out.println(future2.get());
System.out.println(future3.get());
}
Synchronization method
When the synchronized keyword is combined with the method, the method is a synchronous method. Synchronization methods have one implicit lock. When multiple threads execute this method at the same time, it can only be executed sequentially, and threads that are not strong enough to lock are in blocking state. In addition, static methods and non-static methods use different locks, and the locks of non-static methods are object locks, which do not affect each other if two threads call through two objects of this class. Static methods are class locks, that is, Class objects of this class. The synchronization method cannot specify a lock resource, either an this lock or an Class lock.
public class Test {
public static void main(String[] args) throws Exception {
Test test = new Test();
Thread t1 = new Thread(()->{
test.synFunction();
});
Thread t2 = new Thread(()->{
test.synFunction();
});
t1.start();
t2.start();
}
public synchronized void synFunction(){
try {
System.out.println("-------------");
TimeUnit.SECONDS.sleep(3);
}catch (Exception e) {}
}
}
public class Test {
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(()->{
Test.synFunction();
});
Thread t2 = new Thread(()->{
Test.synFunction();
});
t1.start();
t2.start();
}
public static synchronized void synFunction(){
try {
System.out.println("-------------");
TimeUnit.SECONDS.sleep(3);
}catch (Exception e) {}
}
}
Synchronization block
Synchronization code blocks can specify lock objects, non-static methods can specify arbitrary object locks, or arbitrary class locks. However, static methods can only use arbitrary class locks.
public class Test {
public static void main(String[] args) throws Exception {
Test lock = new Test();
Thread t1 = new Thread(() -> {
lock.synFunction();
});
Thread t2 = new Thread(() -> {
lock.synFunction();
});
t1.start();
t2.start();
}
public void synFunction() {
synchronized (this) {// Object lock
try {
System.out.println("-------------");
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
}
}
}
}
public class Test {
public static void main(String[] args) throws Exception {
Test lock1 = new Test();
Test lock2 = new Test();
Thread t1 = new Thread(() -> {
lock1.synFunction(lock1);
});
Thread t2 = new Thread(() -> {
lock2.synFunction(lock2);
});
t1.start();
t2.start();
}
public void synFunction(Object lock) {
synchronized (lock) {// Object lock
try {
System.out.println("-------------");
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
}
}
}
}
public class Test {
public static void main(String[] args) throws Exception {
Test lock1 = new Test();
Test lock2 = new Test();
Thread t1 = new Thread(() -> {
lock1.synFunction();
});
Thread t2 = new Thread(() -> {
lock2.synFunction();
});
t1.start();
t2.start();
}
public void synFunction() {
synchronized (Test.class) {// Class lock
try {
System.out.println("-------------");
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
}
}
}
}
public class Test {
public static void main(String[] args) throws Exception {
ThreadChild t = new ThreadChild();
t.start();
}
}
0
Deadlock
When multiple threads compete for locks, deadlocks may result. A thread that blocks because it does not get a lock will not release the acquired lock. Method 1 acquires locks in the order Test. class, Object. class. Method 2 acquires locks in the order of Object. class, Test. class. The program will fall into deadlock.
public class Test {
public static void main(String[] args) throws Exception {
ThreadChild t = new ThreadChild();
t.start();
}
}
1
Priority
Not all threads are created equally, each thread has a priority, specifying an integer from 0 to 10. When multiple threads are running, virtual machines usually run only the threads with the highest priority, but this is not a strict rule. In Java, 10 is the highest priority and 0 is the lowest priority. The default priority is 5. Not all operating systems support these 11 priorities. For example, Windows has only seven priorities. Priorities (1, 2) (3, 4) (6, 7) (8, 9) do the same.
public class Test {
public static void main(String[] args) throws Exception {
ThreadChild t = new ThreadChild();
t.start();
}
}
2
Suspend
In order to give other threads a chance to run, a thread has 8 ways to pause or indicate that it is ready to pause.
IO can be blocked
The most common way for a thread in a network program to automatically relinquish CPU control is IO blocking. Because CPU is much faster than network and disk, network programs often block while waiting for data to arrive from or send data to the network. Even if only a few milliseconds are blocked, this 1 point is enough time for other threads to complete important tasks.
You can block synchronization objects
Threads will also block when entering 1 synchronization method or code block. If the thread does not have a lock on the synchronized object and another thread owns the lock, the thread pauses until the lock is released. If the lock is never released, the thread will stop permanently.
You can give up
The static method Thread. yield () is invoked to give up control of the thread, which notifies the virtual machine that other threads can be executed first. Abandoning does not release the lock held by the thread, so ideally the abandoned thread should not do any synchronization. If other threads waiting to run are blocked because of synchronization resources owned by this thread, these threads will not run. In effect, control will go back to the only thread that can run, that is, the thread that just gave up, which largely loses the meaning of giving up.
public class Test {
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(() -> {
Test.synFunction("aaaaaaaaaaa");
});
Thread t2 = new Thread(() -> {
Test.synFunction2("bbbbbbbbbb");
});
t1.start();
t2.start();
}
public static void synFunction(String name) {
for (int i = 0;; i++) {
Thread.yield();
System.out.println(name + "--------------" + i);
}
}
public static void synFunction2(String name) {
for (int i = 0;; i++)
System.out.println(name + "--------------"+i);
}
}
Can sleep
Hibernation is a more favorable way to give up. Abandoning simply means that the thread is willing to pause, giving other threads with the same priority a chance to run, while the threads that go to sleep are different, and the dormant threads will pause regardless of whether other threads are ready to run or not. In this way, not only other threads with the same priority will get the opportunity, but also threads with lower priority will be given the opportunity to run. However, the hibernating thread still has all the locks it has acquired. So other threads that require the same lock will still block, avoid putting threads to sleep within synchronization methods or blocks.
public class Test {
public static void main(String[] args) throws Exception {
ThreadChild t = new ThreadChild();
t.start();
}
}
4
public class Test {
public static void main(String[] args) throws Exception {
ThreadChild t = new ThreadChild();
t.start();
}
}
5
You can connect another thread
The connecting thread (the thread A that calls the join () method) waits for the connected thread (join () method to belong to the thread object B) to finish executing before executing. The join () A thread that the A thread calls the B thread waits for the B thread to finish executing before continuing. Note that the A thread does not release the lock resources it has acquired.
public class Test {
public static void main(String[] args) throws Exception {
ThreadChild t = new ThreadChild();
t.start();
}
}
6
You can wait for 1 object
A thread can wait for an object it locks. While waiting, It releases the lock on the object and pauses, Until it is notified by another thread. The other thread modifies this object in some way, Notifies the thread waiting for the object, and then continues execution. Waiting pauses execution until an object or resource reaches a certain state. In fact, to wait for a particular object, the thread wishing to pause must first acquire a lock on the object using synchronized, and then call one of the object's three overloaded wait () methods.
public class Test {
public static void main(String[] args) throws Exception {
ThreadChild t = new ThreadChild();
t.start();
}
}
7
Can end
Threads should give up CPU control in a reasonable way, When the run () method returns to a thread, The thread will undo, Other threads can take over CPU. In network applications, Threads that wrap a blocking operation often do this, For example, a thread downloads a file from the server, So that other parts of the application will not be blocked. Another aspect, If the run () method is too simple, Always end quickly, not violet, and there is a real problem: whether it is necessary to generate a thread. Virtual machines have a lot of overhead when setting up and undoing threads. If threads end in extreme time, using a simple method call instead of a single thread may end faster.
Can be preempted by higher priority threads
Thread
setPriority(int priority)
Set the priority of threads.
Summarize
This article is here, I hope to give you help, but also hope that you can pay more attention to this site more content!